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.
Related
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.
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;
}
I have a requirement to fetch the list containing information of all the users present in the directory. And I'm trying to fetch by the following piece of code:
DirContext ctx = new InitialDirContext(env);
boolean ignoreCase = true;
Attributes matchAttrs = new BasicAttributes(ignoreCase);
matchAttrs.put( new BasicAttribute("") );
//LDAP_Attributes : Attributes of every user e.g. name, phone# etc.
NamingEnumeration answer = ctx.search( "ou=People", matchAttrs, LDAPUser.LDAP_ATTRIBUTES );
I don't have the access to LDAP server owing to security constraints and hence, unable to test the same. Kindly suggest if the above approach is correct. Thanks!
check the below code sample to get the information using Search(). i think it might help you.
AllSearch.java
package usingj2ee.naming;
import javax.naming.*;
import javax.naming.directory.*;
public class AllSearch
{
public static void main(String[] args)
{
try
{
// Get the initial context
InitialDirContext ctx = new InitialDirContext();
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// Search for items with the specified attribute starting
// at the top of the search tree
NamingEnumeration objs = ctx.search(
"ldap://ldap.wutka.com/o=Wutka Consulting, dc=wutka, dc=com",
"(objectClass=*)", searchControls);
// Loop through the objects returned in the search
while (objs.hasMoreElements())
{
// Each item is a SearchResult object
SearchResult match = (SearchResult) objs.nextElement();
// Print out the node name
System.out.println("Found "+match.getName()+":");
// Get the node's attributes
Attributes attrs = match.getAttributes();
NamingEnumeration e = attrs.getAll();
// Loop through the attributes
while (e.hasMoreElements())
{
// Get the next attribute
Attribute attr = (Attribute) e.nextElement();
// Print out the attribute's value(s)
System.out.print(attr.getID()+" = ");
for (int i=0; i < attr.size(); i++)
{
if (i > 0) System.out.print(", ");
System.out.print(attr.get(i));
}
System.out.println();
}
System.out.println("---------------------------------------");
}
}
catch (Exception exc)
{
exc.printStackTrace();
}
}
}
Referenced from here
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).
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=*))