I am facing problem while applying logical not query.
For example,
NamingEnumeration<SearchResult> results =
context.search("ou=people,dc=example,dc=com", "sn=Kumaran", searcCon);
Above statement is working absolutely fine, it is returning all the person entries whose sn is Kumaran.
Suppose that I change the statement to get all the person entries whose sn is not Kumaran.
NamingEnumeration<SearchResult> results =
context.search("ou=people,dc=example,dc=com", "(!sn=Kumaran)", searcCon);
I am getting following error:
Exception in thread "main" javax.naming.directory.InvalidSearchFilterException: Unbalanced parenthesis; remaining name 'ou=people,dc=example,dc=com'
at com.sun.jndi.ldap.Filter.findRightParen(Filter.java:694)
at com.sun.jndi.ldap.Filter.encodeFilterList(Filter.java:733)
at com.sun.jndi.ldap.Filter.encodeComplexFilter(Filter.java:657)
at com.sun.jndi.ldap.Filter.encodeFilter(Filter.java:118)
at com.sun.jndi.ldap.Filter.encodeFilterString(Filter.java:74)
at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:548)
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1985)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1844)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1769)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)
at jndi_tutorial.Test.getPeopleSnIsKumaran(Test.java:34)
at jndi_tutorial.Test.main(Test.java:62)
Following is my code
public static void printResults(NamingEnumeration<SearchResult> results)
throws NamingException {
while (results.hasMoreElements()) {
SearchResult res = results.next();
Attributes atbs = res.getAttributes();
Attribute nameAttr = atbs.get("cn");
String name = (String) nameAttr.get();
Attribute descriptionAtr = atbs.get("description");
String description = (String) descriptionAtr.get();
System.out.println(description);
System.out.println("Name is :" + name + ",description is :"
+ description);
}
}
/* Get all people whose sn is not equal to Kumaran */
public static void getAllExcludeKumaran() throws NamingException {
SearchControls searcCon = new SearchControls();
searcCon.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> results = context.search(
"ou=people,dc=example,dc=com", "(!(sn=Kumaran))", searcCon);
printResults(results);
}
Reference
https://technet.microsoft.com/en-us/library/aa996205(v=exchg.65).aspx
Try to add parenthesis (!(sn=Kumaran))
UPDATE:
Try this
...
SearchControls searcCon = new SearchControls();
String[] attributeFilter = { "cn", "description" };
searcCon.setReturningAttributes(attributeFilter);
searcCon.setSearchScope(SearchControls.SUBTREE_SCOPE);
...
See RFC 2254:
filter ::= "(" filtercomp ")"
not ::= "!" filter
Your code should be like
context.search("ou=people,dc=example,dc=com", "((!sn=Kumaran))", searcCon);
It should work for you.
Related
Here is the method which i have used to fetch but nothing is being populated.
public void doSearch() throws NamingException {
String searchFilter = "(&(ou=Example,ou=Examples_ou)(objectClass=person))";
String domain = "DC=mydom,DC=com";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(domain, searchFilter, searchControls);
int ttl = 0;
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
ttl++;
System.out.println(">>>" + sr.getName());
Attributes attrs = sr.getAttributes();
System.out.println(">>>>>>" + attrs.get("samAccountName"));
}
System.out.println("Total results: " + ttl);
}
Your filter is invalid, thus returns no data. In
ctx.search(domain, searchFilter, searchControls);
domain is being passed as the base DN for the search. If you want to restrict your search to users within ou=Example,ou=Examples_ou of dc=example,dc=com, then your search base DN should be "ou=Example,ou=Examples_ou,dc=example,dc=com" and searchFilter would be simply "(&(objectClass=person))"
I am trying to get all users from my active directory however my code is returning just one row. I have tried the below which is currently only outputting one user.
private void getUserBasicAttributes(String username, LdapContext ctx) {
try {
List<String> usersList = new ArrayList<String>();
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
//First input parameter is search bas, it can be "CN=Users,DC=YourDomain,DC=com"
//Second Attribute can be uid=username
NamingEnumeration<SearchResult> answer = ctx.search("DC=domain,DC=com", "(&(objectCategory=user))"
, constraints);
if (answer.hasMoreElements()) {
Person person = new Person();
SearchResult attrs = ((SearchResult) answer.next());
String names[] = attrs.getName().split(",");
String name[] = names[0].split("=");
usersList.add(name[1]);
}else{
throw new Exception("Invalid User");
}
System.out.println(usersList.size());
} catch (Exception ex) {
ex.printStackTrace();
}
}
You are not looping over all the results, add a while loop inside the if
if (answer.hasMoreElements()) {
while(answer.hasMoreElements()) {
Person person = new Person();
SearchResult attrs = ((SearchResult) answer.next());
String names[] = attrs.getName().split(",");
String name[] = names[0].split("=");
usersList.add(name[1]);
}
}else{
throw new Exception("Invalid User");
}
You need while instead of if:
while (answer.hasMoreElements()) {
Person person = new Person();
SearchResult attrs = ((SearchResult) answer.next());
String names[] = attrs.getName().split(",");
String name[] = names[0].split("=");
usersList.add(name[1]);
}
if (usersList.size() == 0) {
throw new Exception("Invalid User");
}
You can simplify the name-element handling as well. No need to parse the DN. Just specify the attribute(s) you want returned up front and retrieve them directly.
You are making this too hard. No reason to perform any "splitting" pf values.
// Specify the ids of the attributes to return
String[] attrIDs = { "uid" };
// Get ONLY the attributes desired
Attributes answer = ctx.getAttributes("CN=Users,DC=YourDomain,DC=com", attrIDs);
for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
Attribute attr = (Attribute)ae.next();
System.out.println("attribute: " + attr.getID());
/* Print each value */
for (NamingEnumeration e = attr.getAll(); e.hasMore();
System.out.println(e.next()))
;
}
Let me know how I can help.
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;
}
}
Please find my code snippet below:
String[] attrIDs = {"title", "Depatrment", "DivisionDescription" };
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(ldapServerSearchBase, FILTER, ctls);
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
String str_title = attrs.get("title").toString();
String str_dept = null;
String str_desc = null;
if(str_title.equals("Professor"))
{
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
}
System.out.println(str_title);
System.out.println(str_dept);
System.out.println(str_desc);
When I run this code, it always displays null when i output str_dept and str_desc. But it does display str_title correctly as "Professor".
Please help me understand what could be going wrong here.
Thanks!
Are you sure that the attributes you're fetching even exists?
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
Firstly, the Depatrment is spelled wrong, and the DivisionDescription most likely does not exists (at least not in the default schematics for most directory services). Might be you need the following attributes?:
DivisionDescription => division
Depatrment => department
However, check that your directory service actually even posess the requested attributes (and that users actually have some values within these attributes).
Although I am sure, if more information were provided, there is a better method to do this, the example below should get you on your way:
String[] attrIDs = {"title", "Depatrment", "DivisionDescription" };
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> answer = ctx.search(ldapServerSearchBase, filter, ctls);
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
String str_title=null;
String str_dept = null;
String str_desc = null;
if( attrs.get("title")!=null)
{
str_title = attrs.get("title").toString();
System.out.println(str_title);
if(str_title.equals("Professor"))
{
str_dept = attrs.get("Depatrment").toString();
str_desc = attrs.get("DivisionDescription").toString();
System.out.println(str_dept);
System.out.println(str_desc);
}
}
-jim
I have an LDAP attribute which stores multiple values
ie, user details (like firstname, lastname, email address) are stored in one attribute with key value pair.
For example, attribute name='Testuser'. This 'Testuser' attribute as following multi values: firstname=test, lastname=testing
email=testing#xxx.com like this.
Now i want to modify firstname value alone using java code.
(I have searched many sites where i could find single attribute change using ModificationItem)
Here my code snippet:
DirContext ctx = new InitialDirContext(env);
SearchControls ctls = new SearchControls();
ctls.setReturningObjFlag(true);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter;
filter = "(&(objectClass=myobjectclass)(apn=" + userName + "))";
NamingEnumeration answer = ctx.search("o=mydomain", filter, ctls);
while (answer.hasMore()) {
SearchResult sr = (SearchResult)answer.next();
Attributes attrs = sr.getAttributes();
String givenName = " ";
try {
for (NamingEnumeration e = attrs.getAll(); e.hasMore();) {
Attribute attr = (Attribute) e.next();
System.out.println("Attribute name: " + attr.getID());
for (NamingEnumeration n = attr.getAll(); n.hasMore(); System.out
.println("value: " + n.next()));
}} catch (Exception err) {
givenName = " ";
}
}
I am getting following output:
Attribute name: apn
value: testuser
Attribute name: appropertycollection
value: Profile.Contact.ZipCode=46784157
value: Profile.Contact.State=7
value: Profile.Contact.MobileNum=4564545455
value: Profile.Contact.Password=12345
value: Profile.Contact.FirstName=David
value: Profile.Contact.Address=TestAddress456
value: Profile.Contact.Email=asde#xxx.com
value: Profile.Contact.LastName=lastname
Now I want to modify, "Profile.Contact.FirstName=David" value alone which is in a propertycollection Attribute.
Helps are really appreciated.
Thanks!
What about creating a javax.naming.directory.BasicAttribute, add all necessary attributes.
Then, follow the short tutorial here: Oracle tutorial
Please provide me with a short code snippet, so that we see what you agonize over.