I am looking for a query, when entered a name it should check whether there are any sub employees reporting to that entered name. If there are any, then it should return all the list of child users(employees) and sub child users reporting to that employee.
I wrote a query, when entered a username, it gets all the data associated with him, but I am confused now how to get only the users & sub-users & sub-sub users names that report to that search term.
Is there a way to do it with AD or do I need to implement DFS search? If either option, then please give me some hints to do it.
try {
// Create Initial Context
LdapContext ctxGC = new InitialLdapContext(env, null);
// ctxGC.setRequestControls(null);
String searchFilter = "(&(objectClass=user)(sAMAccountName=" + searchTerm + ")(!(displayName=ADM*)))";
NamingEnumeration<?> namingEnum = ctxGC.search("OU=User,DC=emea,DC=xyz,DC=biz", searchFilter, getSearchControls());
Deque<Node> stack = new ArrayDeque<Node>(); // Do I need to implement tree here or is there any other way to get sub users info from LDAP search??
while (namingEnum.hasMoreElements()) {
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
if (attrs != null) {
NamingEnumeration ne = attrs.getAll();
while (ne.hasMore()) {
Attribute attr = (Attribute) ne.next();
}
}
}
namingEnum.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static SearchControls getSearchControls() {
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchCtls.setReturningAttributes(new String[]{"*"});
return searchCtls;
}
To get the list of users reporting to a manager, I just need to change the search filter query and retrieve the manager credentials, then it returns the list of all users that are reporting to that person. If there are no users reporting to him, then it returns nothing.
So, the searchFilter need to be changed like the following.
String searchFilter = "(&(objectClass=user)(manager=CN=Its\\\\, Zaif,OU=xx,OU=xx,OU=StandardUser,OU=xx,DC=emea,DC=xyz,DC=biz) (!(displayName=ADM*)))";
Related
At the same time of providing authentication to the user in LDAP within Microsoft Active Directory, I'm trying to get all groups that specific user belongs to. The following code is in Java.
What I'm doing at the moment is the following:
public static List authenticate(String username, String password) throws Exception {
String LDAPURL = MY_LDAP_URL;
String userBase = MY_USERBASE; //format "dc=***,dc=com"
ArrayList<String> groups = new ArrayList<String>();
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, LDAPURL);
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, username);
environment.put(Context.SECURITY_CREDENTIALS, password);
DirContext ctx =
new InitialDirContext(environment);
SearchControls ctls = new SearchControls();
String[] attributes = {"cn", "memberOf"};
ctls.setReturningAttributes(attributes);
ctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
String searchFilters = "{sAMAccountName="+username+"}";
NamingEnumeration<?> answer = ctx.search(userBase, searchFilters, ctls);
if(answer == null || !answer.hasMore()) {
logger.info("No result found");
}
else {
SearchResult result = (SearchResult) answer.next();
Attributes attrs = result.getAttributes();
Attribute memberAttr = attrs.get("memberOf");
NamingEnumeration e = memberAttr.getAll();
while(e.hasMore()) {
String group = (String) e.next();
groups.add(group);
logger.info(group);
}
}
return groups;
}
I have tried several ways of doing my query, for example:
String searchFilters = "(&(uid="+username+"),(ou=users),(memberOf=*))"
Or
String searchFilters = "(&(objectClass=groupOfNames)(member=cn=" + username + ")(memberOf=*))"
Or
String searchFilters = "(&(userPrincipalName=" + username + ")(memberOf=*))"
In none of the cases any groups were retrieved. In some of the cases the login itself failed as well (in some cases it worked but still no groups returned).
What is the correct way to retrieve the groups?
Although you can bind with "username" and some other attributes, using ANR, ONLY when using Microsoft Active Directory, you will need to obtain the Fully Distinguished Name for the user to perform many LDAP Searches.
Assuming username is the samAccountName, which is always Unique within a AD Forrest, your Authentication should work.
After Authentication you can obtain the DN of the entry and then perform a search for Groups the user is a member.
For all groups the user is a member, including nested groups this will usually work.
(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))
We have several JNDI Examples in a code repository.
I don't know java that much but I need to change a code. The background here is we have the code working in LDAP which will give us the groups assigned to the user which has logged in. Now, we have to switch to OpenLDAP for some reason and here the problem arises. Here we are not able to get the groups assigned to the user.
Previously I was using to get the groups
The context name is here ou=People,dc=maxcrc,dc=com
NamingEnumeration<SearchResult> search
= context.search(contextName,
"(sAMAccountName=" + userId + ")", constraints);
Now, I have tried various combination like
NamingEnumeration<SearchResult> search
= context.search(contextName,
"(uid=" + userId + ")", constraints);
and
NamingEnumeration<SearchResult> search
= context.search(contextName,
"(&(objectClass=groupOfNames)(cn=+userId)", constraints);
and others.
The problem is here I am not getting the groups name. So, is there wrong in how I am searching for groups or what I am not getting. Could anyone please help me.
This is our code
public static HashMap getGroupList(
DirContext context, String userId, String key)
throws NamingException, NullArgumentException,
InvalidStringValueException, ParserException {
//setting sonstraints ans searach control to subtree scope
HashMap groupList = new HashMap();
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
constraints.setReturningAttributes(new String[]{"cn", MEMBER_OF_ATTRIBUTE});
String contextName = parser.getConfigNodeValue("contextName");
logger.debug("Context Name: " + contextName);
logger.debug("Finding Group List for user ID: " + userId);
NamingEnumeration<SearchResult> search
= context.search(contextName,
SAMAC_COUNT_NAME + userId + CLOSE_BRACKET, constraints);
//searching attribute
logger.debug("searching attribute");
SearchResult searchResult = null;
String value = "";
while (search.hasMoreElements()) {
searchResult = search.next();
String groupName = searchResult.getAttributes().get(MEMBER_OF_ATTRIBUTE).toString();
groupList.put(groupName, groupName);
}
return groupList;
}
EDIT:
here context name is ou=People,dc=maxcrc,dc=com and I have applied the various search filter as (uid=userId), also (&(objectClass=groupOfNames)(uid=userId)), also (&(objectClass=user)(uid=userId)), but I am getting nothing out. I need to know how to search in here.
Directory is simple here-
In dc=maxcrc dc=com there is ou=People
and there is a user inside that demo and the demo has is a part of a group. Object class is inetOrgPerson for a user
the output was nothing
That doesn't mean the attribute was empty. If that had been the case you would have seen the output of logger.debug(groupName + " group name found for " + userId);. As you didn't, clearly the search itself didn't return anything, i.e. something wrong with your filter or start DN.
EDIT Re your edit, only the first filter makes sense. The second one is a syntax error, and the third one searches the groups rather than the users, and it is the users that will have the memberOf attribute, not the groups. There is still not enough information here to comment further.
EDIT 2
context name is ou=People,dc=maxcrc,dc=com
OK.
and I have applied the various search filter as (uid=userId)
Do you mean (uid={0}) with a parameter of the value of userId? You should. And what was the value of userId?
this also (&(objectClass=groupOfNames)(uid=userId))
This is just nonsense:
There won't be (shouldn't be) groups under ou=People;
Group objects won't have a memberOf attribute. Users will have a memberOf attribute, showing what groups they are a member of. Looking for that inside the groups makes no sense whatsoever.
this also (&(objectClass=user)(uid=userId))
See above. This requires that user objects have an objectClass of user. Do they? If not, what do they have, and why aren't you using that?
And please answer the question about what the relevant part of the directory tree looks like. Including the object classes.
I was wrong all the time. There is no memberof attribute in our OpenLDAP so the code will not work.
So I need to change the code a little bit such that I authenticate the user and then I should query every group present and check whether that username is present in those groups.
So, even if there is no memberof I can work out.
This is sample code I used-
import javax.naming.NamingException;
public class LdapQuery {
public static void main(String[] args) throws NamingException {
SimpleLdapAuthentication obj = new SimpleLdapAuthentication();
obj.ldapquery();
}
}
and here is the method
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public class SimpleLdapAuthentication {
public String ldapquery() {
String distName = "";
String username = "cn=demo,ou=People,dc=saas,dc=com";
String[] userID = new String[2];
userID[0] = "Users";
userID[1] = "Developers";
int size = userID.length;
String password = "sacs3";
String groupName = "";
String base = "ou=People,dc=maxcrc,dc=com";
//String searchFilter = "cn=" + username + "," + base;
String ldapURL = "ldap://yourldapurl";
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, ldapURL);
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, username);
environment.put(Context.SECURITY_CREDENTIALS, password);
String[] returnAttribute = {"member"};
SearchControls srchControls = new SearchControls();
srchControls.setReturningAttributes(returnAttribute);
srchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
for (int i = 0; i <= size - 1; i++) {
String searchFilter = "(cn=" + userID[i] + ")";
try {
DirContext authContext = new InitialDirContext(environment);
//System.out.println("Authentication Successful");
NamingEnumeration<SearchResult> search = authContext.search(base, searchFilter, srchControls);
// Probably want to test for nulls here
distName = search.nextElement().toString();
String[] splitBasedOnColon = distName.split("\\:");
for (String x : splitBasedOnColon) {
if (x.startsWith("cn")) {
String[] splitGroupName = x.split("\\=");
groupName = splitGroupName[1];
}
}
if (distName.contains(username)) {
System.out.println("User is part of the group: " + groupName);
}
} catch (AuthenticationException authEx) {
System.out.println("Authentication failed!");
} catch (NamingException namEx) {
System.out.println("Something went wrong!");
namEx.printStackTrace();
} catch (NullPointerException notFound) {
System.out.println("User is not part group : "+ userID[i]);
// notFound.printStackTrace();
}
}
return distName;
}
}
I am currently maintaining some library scanning software at a company, and I am at a coop for (I am in high school). I have to be able to pass an employeeID value from the scanner to the LDAP lookup to return a "CN" value.
Unfortunately, I am not getting any results returned in the Java program. I am able to search using the Active Directory program in Windows, but it takes 6 to 10 seconds to display any results from employeeID. I attempted to solve this issue by using a very large timeout limit on the query, but I think I must be doing something wrong.
Anyone with database experience have any ideas?
try
{
System.out.println("Début du test Active Directory");
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(INSERT CREDENTIALS HERE);
env.put("com.sun.jndi.ldap.timeout", "80000");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_PROTOCOL, "simple");
ldapContext = new InitialDirContext(env);
// Create the search controls
SearchControls searchCtls = new SearchControls();
//Specify the attributes to return
String returnedAtts[]={"cn","givenName", "samAccountName"};
searchCtls.setReturningAttributes(returnedAtts);
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//specify the LDAP search filter
id = "********";
String searchFilter = "(&(employeeID="+id+"))";
//Specify the Base for the search
String searchBase = "dc=ericsson,dc=se";
//initialize counter to total the results
SearchResult sr = null;
int totalResults = 0;
NamingEnumeration<SearchResult> answer = ldapContext.search(searchBase, searchFilter, searchCtls);
// Search for objects using the filter
while (totalResults == 0){
answer = ldapContext.search(searchBase, searchFilter, searchCtls);
System.out.println("Total results: " + totalResults);
while (answer.hasMoreElements())
{
sr = answer.next();
System.out.println(sr);
totalResults++;
System.out.println(">>>" + sr.getName());
Attributes attrs = sr.getAttributes();
cn = (">>>>>>>>>" + attrs.get("cn"));
signum = cn.substring(13,20);
System.out.println("Total results: " + totalResults);
}
}
//Loop through the search results
You need to ensure that the employeeID attribute is indexed.
You should also qualify your filter further. I would add at least an objectClass filter, set to whatever object class you're using for people.
I have to get the data for the user which are not part of group OU="Google app User" and OU=Contacts I don't have any idea of creating search filter string. code is given below---
public SearchResult getUserInfo(DirContext ctx) throws NamingException{
SearchResult sourceResult = null;
// Create the search controls
SearchControls searchCtls = new SearchControls();
//Specify the attributes to return
//1 String returnedAtts[]={"ou","description"}; // array of the object list which is returned as the
//result of the search query on ldap active directory
String returnedAtts[]={"cn","description","memberOf"};
searchCtls.setReturningAttributes(returnedAtts);
logger.info("Specify the attributes to return ");
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
logger.info("Specify the search scope ");
//specify the LDAP search filter
//1 String searchFilter = "(&(OU=Contacts))"; // search input variable require to search the result active directory
String searchFilter = "(&(OU=Contacts))";// I wanna create search filter for all reseult which are not group member of OU="google app user"
and OU="contacts".
logger.info("specify the LDAP search filter ");
//Specify the Base for the search
//1 String searchBase ="DC=Hellowveen,DC=com";
String searchBase ="OU=Users,OU=Matriz,OU=Brazil,DC=Hellowveen,DC=com";// "dc=dom,dc=fr"; initial basic search directory
logger.info("Specify the Base for the search ");
//initialize counter to total the results
int totalResults = 0;
// Search for objects using the filter
NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);
logger.info("Search for objects using the filter ");
//Loop through the search results
while (answer.hasMoreElements())
{
sourceResult = (SearchResult)answer.next();
totalResults++;
System.out.println(" get name : >>>" + sourceResult.getName());
System.out.println(" get class name :>>>" + sourceResult.getClassName());
Attributes attrs = sourceResult.getAttributes();
System.out.println("member Off>>>>" + attrs.get("memberOf"));
}
logger.info("Loop END through the search results ");
System.out.println("Total results: " + totalResults);
ctx.close();
return sourceResult;
}
How to search the data in active directory using the java on the base's of group(memberOf) . I really appreciate every suggestion solution. Thanks
The LDAP filer search string representation: RFC 2254
Filter all user which are NOT a member of group "Google app User" but a member of group Contacts:
(&(!(memberOf=ou=Google app User))(memberOf=ou=Contacts))
I'm trying to find the CN of a username by searching for the employeeID attribute (which is unique for each employee). I already got it to return a string with all attributes, but I want it to return only the CN of a user (ex: 'John Doe' or 'cn=John Doe'; both are fine)
public void getEmployeeId(String id) {
// TODO stuff
String groupName = "ou=Accounts,DC=PORTAL,DC=COMPANY,DC=BE";
try {
System.out.println("Creating initial directory context...");
LdapContext ctx = new InitialLdapContext(env, null);
// Create default search controls
SearchControls ctls = new SearchControls();
// Search for user with 'id' as value for employeeID attribute
String filter = "(&(employeeID=" +id + "))";
// Search for objects using filter
NamingEnumeration answer = ctx.search(groupName, filter, ctls);
// Print the answer
// Search.printSearchEnumeration(answer);
System.out.println("-----------------");
System.out.println(answer.next());
System.out.println("-----------------");
// Close the context when we're done
ctx.close();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
note: I know you can just cut parts from a string, but I want it to return only the value I need.
The search request should contain a list of attributes. Some APIs will return all attributes from matching entries. Specify cn in the list of attributes to return, and be prepared to handle a multi-valued cn attribute.
see also
LDAP: Mastering Search Filters
LDAP: Search best practices
LDAP: Programming practices
For example:
DirContext ctx = new InitialDirContext(env);
/***/
NamingEnumeration<?> namingEnum = ctx.search(
"dc=stackoverflow,dc=com, "employeeID=" +id,
ctls);
while (namingEnum.hasMoreElements()) {
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
System.out.println(attrs.get("cn"));
System.out.println(attrs.get("name"));
System.out.println(attrs.get("userPrincipalName"));
}
/***/
the result:
CN: Andres Montejo
NAME: Andres Montejo
userPrincipalName: andresmontejo#stackoverflow.com