Is their any way to fetch duplicates from AD using java ? I see we can do it in power shell by grouping all usernames and then checking count >1.
https://gallery.technet.microsoft.com/scriptcenter/Find-Active-Directory-c8789b42
Please help :).
you should get all objects of a special type(such as user, group , ...) and their attributes. then check duplicate attributes of all objects. for do this, you can insert each attributes in a hasp map as a key, and insert all value of attribute per each object and check is duplicated or not ?
use JAVA JNDI to access AD server as follow:
/**
* retrieve all attributes of a named object.
*
*/
class GetAllAttrs {
static void printAttrs(Attributes attrs) {
if (attrs == null) {
System.out.println("No attributes");
} else {
/* Print each attribute */
try {
for (NamingEnumeration ae = attrs.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("value: " + e.next()))
;
}
} catch (NamingException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>(11);
env
.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");
try {
// Create the initial context
DirContext ctx = new InitialDirContext(env);
// Get all the attributes of named object
Attributes answer = ctx.getAttributes("cn=Ted Geisel, ou=People");
// Print the answer
printAttrs(answer);
// Close the context when we're done
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
also you can use search filter to limit your outputs:
public class LdapSearch {
public static void main(String[] args) throws Exception {
Hashtable env = new Hashtable();
String sp = "com.sun.jndi.ldap.LdapCtxFactory";
env.put(Context.INITIAL_CONTEXT_FACTORY, sp);
String ldapUrl = "ldap://localhost:389/dc=yourName, dc=com";
env.put(Context.PROVIDER_URL, ldapUrl);
DirContext dctx = new InitialDirContext(env);
String base = "ou=People";
SearchControls sc = new SearchControls();
String[] attributeFilter = { "cn", "mail" };
sc.setReturningAttributes(attributeFilter);
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(sn=W*)(l=Criteria*))";
NamingEnumeration results = dctx.search(base, filter, sc);
while (results.hasMore()) {
SearchResult sr = (SearchResult) results.next();
Attributes attrs = sr.getAttributes();
Attribute attr = attrs.get("cn");
System.out.print(attr.get() + ": ");
attr = attrs.get("mail");
System.out.println(attr.get());
}
dctx.close();
}
}
Related
I'm looking for a way to change the OU of a user in my Oracle LDAP, using Java. So far I found only the DirContext.rename method, but that results in a corrupted LDAP entry. Below is the code I tried.
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.REFERRAL, "follow");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10389");
environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
environment.put(Context.SECURITY_CREDENTIALS, "admin");
DirContext ctx = null;
try {
ctx = new InitialDirContext(environment);
String oldCn = "uid=wso21,ou=wso2,ou=Users,dc=WSO2,dc=ORG";
String newCn = "uid=wso21,ou=vodafone,ou=Users,dc=WSO2,dc=ORG";
ctx.rename(oldCn, newCn);
} catch (NamingException e) {
e.printStackTrace();
} finally {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
After this is executed, the moved entry is there but no attributes are present.
TIA!
Please modify try Block:
try {
ctx = new InitialDirContext(environment);
String oldDn = "uid=wso21,ou=wso2,ou=Users,dc=WSO2,dc=ORG";
String newDn = "uid=wso21,ou=vodafone,ou=Users,dc=WSO2,dc=ORG";
String newCn="newCN";
String newSn="newSN";
Attributes attrs = ctx.getAttributes(oldDn);
ctx.rename(oldDn,newDn);
attrs.remove("cn");
attrs.remove("sn");
//if needed remove more attributes
attrs.put("cn",newCn);
attrs.put("sn",newSn);
//if needed add more attributes
ctx.modifyAttributes(newDn, DirContext.ADD_ATTRIBUTE, attrs);
}
I am working on a project which needs ADS integration. I have developed application using java.
I am trying to connect to ADS using LDAP, the same is working fine. It is returning many attributes like (samAccountName, email, givenName etc.) but it is not returning attribute employeeID which is crucial attribute in my application.
Here is the code which I wrote to fetch user attributes.
private static DirContext ldapContext;
private static String LDAP_URL = "ldap://192.168.10.101:3268";
private static String SECURITY_AUTH = "simple";
private static String CTXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
public ADSService() {
}
public static void fetchEmployees(String username, String password){
try
{
Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, CTXT_FACTORY);
ldapEnv.put(Context.PROVIDER_URL, LDAP_URL);
ldapEnv.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTH);
ldapEnv.put(Context.SECURITY_PRINCIPAL, username );
ldapEnv.put(Context.SECURITY_CREDENTIALS, password);
DirContext ldapContext = new InitialDirContext(ldapEnv);
int count = 0;
// Create the search controls
SearchControls searchCtls = new SearchControls();
//Specify the attributes to return
String returnedAtts[]={"sn","givenName", "samAccountName", "mail", "employeeID"};
searchCtls.setReturningAttributes(returnedAtts);
//Specify the search scope
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//specify the LDAP search filter
String searchFilter = "(&(objectCategory=Person)(objectClass=user))";
//Specify the Base for the search
//String searchBase = "dc=dom,dc=fr";
//initialize counter to total the results
int totalResults = 0;
String searchBase = "dc=in,dc=corp,dc=orgname,dc=com";
// Search for objects using the filter
NamingEnumeration<SearchResult> answer = ldapContext.search(searchBase, searchFilter, searchCtls);
//Loop through the search results
while (answer.hasMoreElements())
{
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
count++;
if (attrs != null)
{
NamingEnumeration ne = attrs.getAll();
while (ne.hasMore())
{
Attribute attr = (Attribute) ne.next();
System.out.println("Attribute :: " + attr);
}
ne.close();
}
}
}catch(NamingException ne){
ne.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
Please help me to get employeeID attribute
When i am trying to search password of user from ldap server this
below error displayed
In this code its doesn't return user Password in String. It throws
java.lang.ClassCastException: [B cannot be cast to java.lang.String
Code:
public class selectEntry {
DirContext ldapContext = null;
public selectEntry() {
try {
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, url);
environment.put(Context.SECURITY_AUTHENTICATION, conntype);
environment.put(Context.SECURITY_PRINCIPAL, AdminDn);
environment.put(Context.SECURITY_CREDENTIALS, password);
ldapContext = new InitialDirContext(environment);
System.out.println("Bind successful");
} catch (Exception exception) {
exception.printStackTrace();
}
}
public void getEntry() {
try {
SearchControls searcCon = new SearchControls();
searcCon.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results
= ldapContext.search("uid=aruhat.aruhat,ou=openzki,dc=aruhat,dc=co,dc=in", "(uid=aruhat.aruhat)", searcCon);
if (results != null) {
while (results.hasMore()) {
SearchResult res = (SearchResult) results.next();
Attributes atbs = res.getAttributes();
Attribute atb = atbs.get("userPassword");
String name = (String) atb.get();
System.out.println("Name is :=> " + name);
}
} else {
System.out.println("fail");
}
} catch (Exception e) {
System.out.println("Exception Type:=> "+e);
System.out.println("Exception Message:=> "+e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
new selectEntry().getEntry();
}
}
LDAP passwords are stored as hashes, not strings. The attribute value is returned as a byte[], as the exception says.
However you don't have any good reason for obtaining the hashed password attribute in the first place. It won't do you any good. Review your requirement. You should be binding as the user using the old password to test whether it's valid, not trying to read the password, which you won't get.
Retreiving binary attributes requires the ;binary suffix, e.g., userCertificate;binary. Then you have the Attribute object. Invoke
byte[] bytes = (byte[]) attr.get()
and you are done. Don't work with toString() or (String) cast.
I want to query my ldap to give me all users where sn contains a specific value (maier). However I always get a single result.
public LdapContext getLdapContext(){
LdapContext ctx = null;
try{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://ldap.url:389");
ctx = new InitialLdapContext(env, null);
System.out.println("Connection Successful.");
}catch(NamingException nex){
System.out.println("LDAP Connection: FAILED");
nex.printStackTrace();
}
return ctx;
}
private User getUserBasicAttributes(String username, LdapContext ctx) {
User user=null;
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = { "distinguishedName",
"sn",
"givenname",
"mail",
"telephonenumber"};
constraints.setReturningAttributes(attrIDs);
constraints.setCountLimit(200);
NamingEnumeration answer = ctx.search("DC=myDc,DC=com", "sn=*maier*", constraints);
if (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
System.out.println("distinguishedName "+ attrs.get("distinguishedName"));
System.out.println("givenname "+ attrs.get("givenname"));
System.out.println("sn "+ attrs.get("sn"));
System.out.println("mail "+ attrs.get("mail"));
System.out.println("telephonenumber "+ attrs.get("telephonenumber"));
}else{
throw new Exception("Invalid User");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return user;
}
Did I do anything wrong?
You're not looping, so of course you're only getting one result. Change if (answer.hasMore()) to while (answer.hasMore()).
I'm trying to change the mail and password attributes of Active Directory using java. To do this, it was generated a security certificate and imported into the certificate store of the jvm (carcerts). The connection is made using ssl successfully however when trying to change any field, eg mail,I get the following error message:
javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00002035: LdapErr: DSID-0C090B3E, comment: Operation not allowed through GC port, data 0, v1db1
source code:
// change mail
private void salvarEmailESenhaNoAd() throws IOException, NamingException {
Properties mudaSenhaProperties = new PropertiesFactory().propertiesByJndi("mudaSenha");
ADUtil adUtil = null;
try
{
adUtil = new ADUtil(mudaSenhaProperties);
adUtil.changeEmail("CN=018061671627,OU=SDS,OU=CS,OU=STI,OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", dadosUsuario.getEmail());
}
finally
{
if (adUtil != null)
{
adUtil.close();
}
}
}
public class ADUtil {
private LdapContext ldapContext = null;
public ADUtil(Properties properties) throws NamingException
{
ldapContext = createUserContext(properties);
}
private LdapContext createUserContext(Properties properties) throws NamingException {
String javaNamingFactoryInitial = properties.getProperty("java.naming.factory.initial");
String javaNamingProviderUrl = properties.getProperty("java.naming.provider.url");
String javaNamingSecurityAuthentication = properties.getProperty("java.naming.security.authentication");
String javaNamingSecurityPrincipal = properties.getProperty("java.naming.security.principal");
String javaNamingSecurityCredentials = properties.getProperty("java.naming.security.credentials");
String javaNamingSecurityProtocol = properties.getProperty("java.naming.security.protocol");
String javaNamingReferral = properties.getProperty("java.naming.referral");
String javaNetSslTrustStore = properties.getProperty("javax.net.ssl.trustStore");
String javaNetSslTrustStorePassword = properties.getProperty("javax.net.ssl.trustStorePassword");
Hashtable<String, String> env = new Hashtable<String, String>();
System.setProperty("javax.net.ssl.trustStore", javaNetSslTrustStore);
System.setProperty("javax.net.ssl.trustStorePassword", javaNetSslTrustStorePassword);
env.put(Context.INITIAL_CONTEXT_FACTORY, javaNamingFactoryInitial);
env.put(Context.SECURITY_AUTHENTICATION, javaNamingSecurityAuthentication);
env.put(Context.SECURITY_PRINCIPAL, javaNamingSecurityPrincipal);
env.put(Context.SECURITY_CREDENTIALS, javaNamingSecurityCredentials);
env.put(Context.SECURITY_PROTOCOL, javaNamingSecurityProtocol); // para poder modificar password y grupos del usuario.
env.put(Context.PROVIDER_URL, javaNamingProviderUrl);
env.put(Context.REFERRAL, javaNamingReferral);
return new InitialLdapContext(env, null);
}
public void changePassword(String userCN, String newPassword) throws NamingException, UnsupportedEncodingException, IOException {
modifyAdAttribute(userCN, "unicodePwd", converteString(newPassword));
System.out.println("Password changed for " + userCN);
}
public void changeEmail(String userDN, String newEmail) throws NamingException, UnsupportedEncodingException, IOException {
modifyAdAttribute(userDN, "mail", converteString(newEmail));
System.out.println("Email changed for " + newEmail);
}
private void modifyAdAttribute(String userCN, String attribute, Object value) throws NamingException{
ModificationItem[] modificationItem = new ModificationItem[1];
modificationItem[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute(attribute, value));
ldapContext.modifyAttributes(userCN, modificationItem);
}
private static byte[] converteString(String password) throws UnsupportedEncodingException{
String newQuotedPassword = "\"" + password + "\"";
return newQuotedPassword.getBytes("UTF-16LE");
}
public void close() throws NamingException
{
if (ldapContext != null)
{
ldapContext.close();
}
}
Reading the attributes is usually done with the code below:
public class TesteLdap {
/**
* #param args the command line arguments
*/
private static SearchControls getSimpleSearchControls() {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setTimeLimit(30000);
//String[] attrIDs = {"objectGUID"};
//searchControls.setReturningAttributes(attrIDs);
return searchControls;
}
public static void main(String[] args) throws NamingException {
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "user");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.REFERRAL, "ignore");
String filter = "(&(objectClass=user)(CN=018061671627))";
LdapContext ctx = new InitialLdapContext(env, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum = ctx.search("OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", filter, getSimpleSearchControls());
while (namingEnum.hasMore()) {
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
System.out.println(attrs.get("cn"));
System.out.println(attrs.get("displayname"));
System.out.println(attrs.get("mail"));
System.out.println(attrs.get("distinguishedName"));
}
namingEnum.close();
} catch (Exception e) {
e.printStackTrace();
My environment: Active Directory on Windows 2008R2 Standart, Open JDK 7 running on unbutu 12.10.
I would be grateful if someone help me because I've tried everything but I can not make it work.
The error seems to be self-explanatory. You should perform this operation over LDAPS using port 636.
Have you tried to use
env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:636");
(Note that ldaps:// is not mandatory if you specify ssl separately).
Do you have RODCs (Read only DCs) in your environment? And if so, is rndc10.tre-rn.jus.br a RODC?
Perhaps you should be pointing to a DC that is writeable?
Have you tried updating this string:
env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");
to:
env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:3269");
^