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.
Related
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 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.
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 know there is a simple answer but I can't seem to find it anywhere.
Below is a small snippet of code. Can someone tell me how to list all the attributes and their associated values for the rsa object?
Thanks in advance,
NamingEnumeration answer = executeSearch(context,env,sBaseDN);
while (answer.hasMore()) { // For each ou
SearchResult sr = (SearchResult) answer.next();
Attributes rsa = sr.getAttributes();
// How do I list all the attributes that were returned?
You can get the collection of NamingEnumerations by calling the getAll() method of Attributes and then iterate over this collection to get attributes values, like:
try {
for (NamingEnumeration attr = rsa.getAll(); attr.hasMore();) {
Attribute attribute= (Attribute) attr.next();
System.out.println("Attribute id: " + attribute.getID());
for (NamingEnumeration val = attribute.getAll(); val.hasMore();){
System.out.println("Attribute value: " + val.next());
}
}
} catch (NamingException e) {
e.printStackTrace();
}
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))