I've read several articles here on StackOverflow on how to get the value of the "unicodePwd" attribute in AD (Active Directory), but none of these articles helped me in this situation.
Well, why do I need this information? I'll explain:
I have here several java routines that unify information from users of different systems with one another. These routines take the necessary information from a main Oracle database and then enter the information into other databases (Oracle and MySQL, basically).
For example: I have an internal private cloud system that runs on a Linux CentOS operating system and has its own MySQL database. To unify user information, including access passwords, I get the information in that Oracle main database and enter them into the system's MySQL database, to unify user details and login information.
As I said, I have several routines that are working correctly without problems, but now we have a new challenge.
I need to do the same unification with our AD (Active Directory) users, that is, I need to get user information in the main Oracle database, including the password, to enter the same AD users. >
I've been able to successfully update the password field on some test users in AD, but I do not want the password to be updated every time this routine runs, but only when the password is changed in the main database Oracle.
Example: When a user swaps his password into the main Oracle database, the java routine will collect all the information to enter into the same user, only from the AD. To do this properly, the routine picks up the same information in the AD and then compares the passwords (Oracle password and AD password) and finally, if the passwords are different, the routine will update the AD password using the password, but if the passwords are the same, the routine will not do anything.
That's why I need to retrieve / get the value of the "unicodePwd" attribute in Active Directory.
Here's part of the code:
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import org.apache.commons.mail.EmailException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
public class ldapQuery {
String distinguishedName = "";
String department = "";
String physicalDeliveryOfficeName = "";
String telephoneNumber = "";
String mobile = "";
String title = "";
String sAMAccountName = "";
String unicodePwd = "";
public ldapQuery(String mail) {
try {
final Hashtable<String, String> env = new Hashtable<String, String>();
final String adminName = "CN=MY DOMAIN ADMIN,CN=MY DOMAIN ADMIN FOLDER LOCALIZATION,DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
final String adminPasswd = "MY DOMAIN ADMIN PASSWORD";
final String ldapUrl = "ldaps://MY ACTIVE DIRECTORY SERVER:636";
final String factory = "com.sun.jndi.ldap.LdapCtxFactory";
final String authType = "simple";
final String protocol = "ssl";
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
env.put(Context.SECURITY_AUTHENTICATION, authType);
env.put(Context.SECURITY_PRINCIPAL, adminName);
env.put(Context.SECURITY_CREDENTIALS, adminPasswd);
env.put(Context.SECURITY_PROTOCOL, protocol);
env.put(Context.PROVIDER_URL, ldapUrl);
DirContext ctx = new InitialLdapContext (env,null);
SearchControls searchCtls = new SearchControls();
String returnedAtts[] = {"sAMAccountName", "distinguishedName","department", "physicalDeliveryOfficeName", "telephoneNumber", "mobile", "title", "unicodePwd"};
searchCtls.setReturningAttributes(returnedAtts);
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchFilter = "(&(objectClass=user)(mail=" + mail +"))";
String searchBase = "DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
int totalResults = 0;
NamingEnumeration<SearchResult> answer =ctx.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult)answer.next();
totalResults++;
Attributes attrs = sr.getAttributes();
if (attrs != null) {
distinguishedName = (String) attrs.get("distinguishedName").get();
department = (String) attrs.get("department").get();
physicalDeliveryOfficeName = (String) attrs.get("physicalDeliveryOfficeName").get();
telephoneNumber = (String) attrs.get("telephoneNumber").get();
mobile = (String) attrs.get("mobile").get();
title = (String) attrs.get("title").get();
sAMAccountName = (String) attrs.get("sAMAccountName").get();
Attribute passwd = attrs.get("unicodePwd");
unicodePwd = unicodePwd + passwd;
if (department == null) {
department = "";
}
if (physicalDeliveryOfficeName == null) {
physicalDeliveryOfficeName = "";
}
if (telephoneNumber == null) {
telephoneNumber = "";
}
if (mobile == null) {
mobile = "";
}
if (title == null) {
title = "";
}
}
}
}
catch (NamingException e){
System.err.println("FAIL MESSAGE: " + e);
}
}
public String ldapSearchResultDistinguishedName() {
return distinguishedName;
}
public String ldapSearchResultDepartment() {
return department;
}
public String ldapSearchResultPhysicalDeliveryOfficeName() {
return physicalDeliveryOfficeName;
}
public String ldapSearchResultTelephoneNumber() {
return telephoneNumber;
}
public String ldapSearchResultMobile() {
return mobile;
}
public String ldapSearchResultTitle() {
return title;
}
public String ldapSearchResultUnicodePwd() {
return unicodePwd;
}
public String ldapSearchResultSAMAccountName() {
return sAMAccountName;
}
}
After running this code, all variables returned the correct values, minus the "unicodePwd" variable, which returned "null", even if the user has a valid password.
I know about the UTF-16LE byte business and that the "unicodePwd" field in Active Directory is encrypted, but, as I explained before, I need this information to be returned decrypted in a String variable.
Any ideas?