LDAP search in java: DN contains , - java

I'm currently running into issues when searching for entries where the DN contains a comma:
StringTokenizer st = new StringTokenizer(dn, "=");
Attributes searchAttributes = new BasicAttributes(st.nextToken(), st.nextToken());
Enumeration results = ctx.search(baseDn, searchAttributes);
if (results.hasMoreElements()) {
// ...
}
I tested both dn=first,second as well as dn=first\,second, and although the search runs correctly, I never get any results back. The same baseDn and dn works correctly in Eclipse/Apache Directory Studio LDAP Browser.

depends of libraries, for example by using Novell ldap.jar is constuctor
searchResults = lc.search(searchBase, searchScope, searchFilter, null, false);
//private String searchFilter = "(objectClass=*)";
again depends or libraries, because maybe Directory Studio LDAP Browser has own driver, and some methods are implemented another maybe not, for example with ldap.jar is able to seach in ActiveDirectory
basically all libraries (including Java driver for Windows ActiveDirectory) contains tons of examples packed with library, for most importand of methods which are implemented into driver
EDIT:
hmmm, but there are two relevant
1/ access for context given by admin (between enviroments)
2/ with ActiveDirectory (always) and with (old PC) test enviroment for LDAP I must force for thread(s) some small pause
private void readData() {
searchResults = new LDAPSearchResults();
try {
Thread.sleep(450);
} catch (InterruptedException ex) {
Logger.getLogger(Profylaxia.class.getName()).log(Level.SEVERE, null, ex);
}
try {
searchResults = lc.search(searchBase, searchScope, searchFilter, null, false);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(Profylaxia.class.getName()).log(Level.SEVERE, null, ex);
}
int noResult = searchResults.getCount();
System.out.println(" noResult : " + noResult);
// thenafter I can able to start Iterations....

The quoting rules for ldap queries can be found at http://www.rlmueller.net/CharactersEscaped.htm
I'm using the following code snippet to query the cn, should work teh same for the dn:
String searchFilter = "(&(objectClass=user)(cn=" + query + "))";
SearchControls searchControls = new SearchControls();
String[] resultAttributes = {"cn", "distinguishedName", "displayName", "lastLogon", "description"};
searchControls.setReturningAttributes(resultAttributes);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration ne = getContext().search(root, searchFilter, searchControls);
List<DirectoryUser> result = new ArrayList<DirectoryUser>();
while (ne.hasMoreElements()) {
SearchResult searchResult = (SearchResult)ne.nextElement();
Attributes attrs = searchResult.getAttributes();
...
}

Related

Java NamingEnumeration - Getting a single element out of a NamingEnumeration

I am trying to fetch some users from Active Directory group and update them in another one of our site.
The task is almost done except for the part where I need to fetch the user ID from NamingEnumeration and pass it onto another method which will update it through a REST API call. Below is a part of the code where I am fetching users from AD group:
DirContext myContext = new InitialDirContext(envVars);
SearchControls searchCtrls = new SearchControls();
searchCtrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attributes = { "cn", "member"};
searchCtrls.setReturningAttributes(attributes);
String filter = "(&(objectClass=group)(cn=GROUP_NAME))";
NamingEnumeration values = myContext.search("DC=XXXX,DC=XXXX",filter,searchCtrls);
while (values.hasMoreElements())
{
SearchResult result = (SearchResult) values.next();
Attributes attribs = result.getAttributes();
if (null != attribs)
{
for (NamingEnumeration ae = attribs.getAll(); ae.hasMoreElements();)
{
Attribute atr = (Attribute) ae.next();
String attributeID = atr.getID();
for (
Enumeration vals = atr.getAll();
vals.hasMoreElements();
System.out.println(attributeID+": "+vals.nextElement())
);
}
}
}
When I run this, the output is something like below:
member: CN=USERNAME,OU=XXX,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX
member: CN=USERNAME,OU=XXX,OU=XXX,OU=XXX,DC=XXX,DC=XXX,DC=XXX
Basically, I need to fetch this CN i.e. USERNAME alone, which I will pass onto another method.
I did try to get them in a String array and process them, to no avail and I am running short of time.
Any ideas would be greatly appreciated. Thanks.
Well, I did get around this problem.
Below approach worked for me.
if (null != attribs)
{
for (NamingEnumeration ae = attribs.getAll(); ae.hasMoreElements();)
{
Attribute atr = (Attribute) ae.next();
for (
Enumeration vals = atr.getAll();
vals.hasMoreElements();
) {
list.add(vals.nextElement().toString());
}
}
}
I let the output inside a list and clipped the unwanted parts to obtain the CN alone.
Would be glad if this helps someone in the future.

Java DirContext sreach only few records

When I try to search records by using query (testAtt=1) in Apache Directory Studio they showing me 17062 records and when I run the same query on my Java code they get only 8531 records. My Java Code is given below
String searchFilter = propFile.getProperty(Constants.GetAllUsersQuery);
String ldapSearchBase = propFile.getProperty(Constants.eDir_SearchBase);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> resultsApp = ctx.search(ldapSearchBase, searchFilter, searchControls);
int i = 0;
while (resultsApp.hasMoreElements()) {
SearchResult result = (SearchResult) resultsApp.next();
String DN = "";
DN = result.getNameInNamespace();
if (!DN.isEmpty()) {
eDir_AllUsersDNList.add(i, DN);
i++;
}
resultsApp.nextElement();
}
System.out.println("eDir_AllUsersDNList : "+eDir_AllUsersDNList.size());
Please help me to find out the issue.
I am using Java 8.
while (resultsApp.hasMoreElements()) {
SearchResult result = (SearchResult) resultsApp.next();
String DN = "";
DN = result.getNameInNamespace();
if (!DN.isEmpty()) {
eDir_AllUsersDNList.add(i, DN);
i++;
}
resultsApp.nextElement();
}
Remove the final nextElement() call. It is doing nothing useful, and it is skipping all the even-numbered elements. Note that 8531 is half of 17062.
NB the cast is redundant, and the DN can't be empty, and providing an initializer for it when you assign it on the very next line is pointless.

JAVA LDAP : How do I obtain the Dn?

I did an LDAP Directory Search and received some results. I need to iterate over these results and display the Dn for each entry.
In my test environment I returned the Dn value by obtaining the value of the entryDN attribute.
In the production environment the entryDN attribute always returns null.
In both environments when I return the value of the Dn attribute all I get is null.
What I really need to do is reliably obtain the Dn from any environment.
Suggestions?
To reliably get the Dn use the method SearchResult.getNameInNamespace();
Building on user2135970's answer, it's not pretty to mix JNDI with Spring LDAP, but it can be done:
private String getDistinguishedName(String addtlFilter) throws NamingException {
String dn = null;
LdapContextSource contextSource = (LdapContextSource) ldapTemplate.getContextSource();
SearchControls ctrls = new SearchControls();
ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);
DirContext dc = null;
try {
dc = ldapTemplate.getContextSource().getContext(contextSource.getUserDn(), contextSource.getPassword());
final String filter = String.format("(&(%s)%s)", addtlFilter, searchFilter);
NamingEnumeration<SearchResult> results = dc.search(searchBase, filter, ctrls);
if (results.hasMore()) {
dn = results.next().getNameInNamespace();
}
} finally {
if (dc != null) {
dc.close();
}
}
return dn;
}

Ldap get users in a distribution list

I'm trying to get all the users of a DL using below code.The code is working as expected. However, I'm not able to get AD usernames for some users. Ex. First row of the o/p has username rkama but not the second row. Is this LDAP data issue or is there a different way to get user name/email address in a DL.
O/p
Entry is : CN=Ay\,Ram(rkama),OU=Site-SJN,OU=Accounts_User,DC=corp,DC=XXX,DC=com
Entry is : CN=Wang\,Peter(),OU=Site-SJN,OU=Accounts_User,DC=corp,DC=XXX,DC=com
public ArrayList<String> getAllDLs(String dlname) throws NamingException {
ArrayList<String> dls = new ArrayList<String>();
String attributes[] = { "member", "displayName" };
createDLContext();
SearchControls ctrl = new SearchControls();
ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctrl.setReturningAttributes(attributes);
String search = "(&(objectClass=group)((sAMAccountName="+dlname+"*)))";
NamingEnumeration enumeration = dlContext.search("", search, ctrl);
while (enumeration.hasMoreElements()) {
SearchResult result = (SearchResult) enumeration.next();
System.out.println("Found match & result is : " + result);
NamingEnumeration<?> n2 = result.getAttributes().get("member").getAll();
while (n2 != null && n2.hasMore()) {
String dlList = (String) n2.next();
System.out.println("Entry is : " + dlList);
}
}
dlContext.close();
return dls;
}
I think you need to escape the \ character. Have a look at http://www.rlmueller.net/CharactersEscaped.htm
The member element only contains a DN for the user, this is not the username or password of the account, but a value that can be put back into the search to get the user information (including cn - the name of the user, and sAMAccountName - the userid of the user).
So you need to feed the dlList value into a second search (cleanly) e.g.
NamingEnumeration searchResult = dlContext.search("", "(dn={1})", new Object[]{ dlList }, ctrl);
Trying to construct the search with a simple string like "(&(objectClass=group)((sAMAccountName="+dlname+"*)))" will yield problems because the elements of the returned string will need to be escaped before putting it into the search (the \ for example).

Java- Retrieving permissions from LDAP for shiro

im trying to get the User Permissions (read, write, browse,...) for LDAP objects using a java application with shiro. I dont have much experience with LDAP. I set up a server with Apache Directory Studio for testing purpose. Then i created a domain (dc=testdomain) and added a subentry with the "accessControlSubentry" objectclass and added the "prescriptiveACI" attribute. Everthing works the way it should if i browse the server with Apache DS and i can connect to the server in my java app.
In order to get the permissions i subclassed the ActiveDirectoryRealm from shiro. But i cant manage to make the query get the subentrys.
private Set<String> getPermissionsForUser(String username, LdapContext ldapContext) throws NamingException{
Set<String> permissions;
permissions = new LinkedHashSet<String>();
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchCtls.setReturningAttributes(new String[]{"prescriptiveACI"});
String searchFilter = "(objectClass=subentry)";
String searchBase = "dc=testdomain";
NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
if (log.isDebugEnabled()) {
log.debug("Retrieving permissions for user [" + sr.getName() + "]");
}
Attributes attrs = sr.getAttributes();
if (attrs != null) {
NamingEnumeration ae = attrs.getAll();
while (ae.hasMore()) {
Attribute attr = (Attribute) ae.next();
if (attr.getID().equals("prescriptiveACI")) {
if (log.isDebugEnabled()) {
log.debug("Permissions found");
}
}
}
}
}
return permissions;
}
When I change the searchFilter to "(objectClass=*)" i get all the OrganisationUnits in the domain. But i just cant seem to find the subentry objects that i need for the prescriptiveACI attribute.
Here is the content of my Shiro.ini file
activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealmPermissions
activeDirectoryRealm.systemUsername = uid=admin,ou=system
activeDirectoryRealm.systemPassword = secret
activeDirectoryRealm.url = ldap://localhost:10389
activeDirectoryRealm.searchBase = ""
How can i make the search query subentries? Or is there a better/alternative way to get the permission from the LDAP server?
So you want to find all instances of accessControlSubentry objects with a prescriptiveACI attribute?
Try this:
(&(objectClass=accessControlSubentry)(prescriptiveACI=*))

Categories

Resources