From 3ae4dba8fea508083f010300deb077abb1425ebf Mon Sep 17 00:00:00 2001
From: Joern Muehlencord
- * Important:
If you want to use ldaps - usually port 636 make sure you
- * provide a trustkeystore in case your ldap server does not use a
- * certificate which can be trusted by the build in root certificates. (e.g.
- * self signed certificates)
If you want to use ldaps - usually port 636 make sure you provide a trustkeystore in case your ldap server does not use a certificate which can be trusted by the build in root
+ * certificates. (e.g. self signed certificates)
- * To provide access to a trust center you can specify the following - * parameter to your application by providing the following parameter + * To provide access to a trust center you can specify the following parameter to your application by providing the following parameter *
* -Djavax.net.ssl.trustStore=/path/to/truststore.keystore
*
*
- * @param url the url of the ldap server to connect to like
- * ldap://ldapserver.your.domain:389
- * @param searchBase the search base to use - e.g.
- * DC=wincor-nixdorf,DC=com
+ * @param url the url of the ldap server to connect to like ldap://ldapserver.your.domain:389
+ * @param searchBase the search base to use - e.g. DC=wincor-nixdorf,DC=com
* @param username the username to connect with
* @param password the password to connect with
*/
@@ -57,24 +61,19 @@ public class LDAPSearch {
* Creates a new instance of a ldap search.
*
*
- * Important:
If you want to use ldaps - usually port 636 make sure you
- * provide a trustkeystore in case your ldap server does not use a
- * certificate which can be trusted by the build in root certificates. (e.g.
- * self signed certificates)
- * To provide access to a trust center you can specify the following - * parameter to your application by providing the following parameter + * To provide access to a trust center you can specify the following parameter to your application by providing the following parameter *
* -Djavax.net.ssl.trustStore=/path/to/truststore.keystore
*
*
* @param authentication the authentification type to use -e.g. "SIMPLE"
- * @param url the url of the ldap server to connect to like
- * ldap://ldapserver.your.domain:389
- * @param securityProtoco the security protocol to use - e.g. SIMPLE
- * @param searchBase the search base to use - e.g.
- * DC=wincor-nixdorf,DC=com
+ * @param url the url of the ldap server to connect to like ldap://ldapserver.your.domain:389
+ * @param securityProtocol the security protocol to use - e.g. SIMPLE
+ * @param searchBase the search base to use - e.g. DC=wincor-nixdorf,DC=com
* @param username the username to connect with
* @param password the password to connect with
*/
@@ -136,7 +135,7 @@ public class LDAPSearch {
// prepare search parameters
String[] resultattributes = {"objectClass", "name", "givenName", "sn", "department", "co", "telephoneNumber", "sAMAccountName", "c",
- "userAccountControl", "managedBy", "distinguishedName", "mail"};
+ "userAccountControl", "managedBy", "distinguishedName", "mail", "lastLogon", "lastLogonTimestamp"};
String searchfilter = "(" + searchField + "=" + searchValue + ")";
SearchControls searchcontrols = new SearchControls();
String[] resultAttributes = resultattributes;
@@ -168,8 +167,7 @@ public class LDAPSearch {
}
/**
- * Returns true, if the given email address can be found in the configured
- * ldap
+ * Returns true, if the given email address can be found in the configured ldap
*
* @param email the emailaddress to search for
* @return true, if the email address could be found; else false
@@ -180,12 +178,10 @@ public class LDAPSearch {
}
/**
- * Returns true, if the given email address is member of the given group,
- * specified by the DN
+ * Returns true, if the given email address is member of the given group, specified by the DN
*
* @param email the email to validat
- * @param groupDn the group search base - all members must be found as
- * "member" in this group
+ * @param groupDn the group search base - all members must be found as "member" in this group
* @return
*/
public boolean isMemberOfGroup(String email, String groupDn) throws LDAPException {
@@ -231,11 +227,13 @@ public class LDAPSearch {
private LDAPContact createLDAPContact(Attributes attributes) throws LDAPException {
LDAPContact ldapContact = new LDAPContact();
+ ldapContact.setEnabled(true);
+ long userAccountControlNumber = 0;
if (attributes.get("mail") != null) {
ldapContact.setEmailaddress(attributes.get("mail").toString());
} else {
- ldapContact.setEmailaddress("");
+ ldapContact.setEmailaddress("");
}
if (attributes.get("objectClass") != null) {
@@ -298,18 +296,19 @@ public class LDAPSearch {
crmname = crmname.substring(crmname.indexOf(":") + 2);
ldapContact.setCrmname(crmname);
}
+
if (attributes.get("userAccountControl") != null) {
String userAccountControl = attributes.get("userAccountControl").toString();
userAccountControl = userAccountControl.substring(userAccountControl.indexOf(":") + 2);
- if (userAccountControl.equals("512")) {
- ldapContact.setEnabled(true);
- } else {
- ldapContact.setEnabled(false);
- }
- } else {
- ldapContact.setEnabled(false);
+ userAccountControlNumber = Long.parseLong(userAccountControl);
+ BitSet bitSet = BitSet.valueOf(new long[]{userAccountControlNumber});
+ // bitSet.get(1) = binary value 2 = UF_ACCOUNT_DISABLE
+ // if bit is set, value is 2
+ // if bit is set, account is disabled
+ ldapContact.setEnabled(!bitSet.get(1));
}
break;
+
case LDAPContact.TYPE_GROUP:
case LDAPContact.TYPE_PUBLICFOLDER:
// handle groups
@@ -342,19 +341,57 @@ public class LDAPSearch {
}
+ // some workarounds - seems to bit 2 is set too often / too early
+ if (!ldapContact.isEnabled()) {
+
+ if (userAccountControlNumber == 66050) {
+ // locked = 2
+ // normal account = 512
+ // password does not expire = 65536
+ // service users / mailbox groups or similar created as normal user
+ ldapContact.setEnabled(true);
+ } else if ((attributes.get("lastLogon") == null) && (attributes.get("lastLogonTimestamp") == null)) {
+ // users without lastLogon date - probably distribution lists etc
+ ldapContact.setEnabled(true);
+ LOGGER.info("Found locked user without lastLogon - probably a shared mailbox - asuming user is still active");
+ } else if ((attributes.get("lastLogon") != null) || (attributes.get("lastLogonTimestamp") != null)) {
+ // check if users have been logged in recently
+ String lastLogonDateString;
+ if (attributes.get("lastLogon") == null) {
+ lastLogonDateString = attributes.get("lastLogonTimestamp").toString();
+ } else {
+ lastLogonDateString = attributes.get("lastLogon").toString();
+ }
+
+ if (lastLogonDateString.contains(":")) {
+ lastLogonDateString = lastLogonDateString.substring(lastLogonDateString.indexOf(":") + 1).trim();
+ }
+
+ long lastLogonDate = Long.parseLong(lastLogonDateString);
+ if (lastLogonDate == 0) {
+ ldapContact.setEnabled(true);
+ LOGGER.info("Found locked user without lastLogon - probably a shared mailbox - asuming user is still active");
+ } else {
+ lastLogonDate = (lastLogonDate / 10000L) - +11644473600000L;
+
+ Date date = new Date(lastLogonDate);
+ LocalDateTime lastLogonDateTime = DateUtil.getDateTime(date);
+
+ LocalDateTime referenceDate = DateUtil.getUtcDateTime(DateUtil.getCurrentTimeInUTC());
+ referenceDate = referenceDate.minus(120, ChronoUnit.DAYS);
+
+ if (lastLogonDateTime.isAfter(referenceDate)) {
+ ldapContact.setEnabled(true);
+ LOGGER.info("Found locked user who recently logged in - asuming user is still active");
+ }
+ }
+ }
+ }
+
+ if (!ldapContact.isEnabled()) {
+ LOGGER.info("User {} is locked", ldapContact.getEmailaddress());
+ }
+
return ldapContact;
}
}
-
-/**
- * History:
- *
- * $$Log: src/main/java/com/wincornixdorf/shared/network/ldap/LDAPSearch.java $
- * Revision 1.1 2013/12/16 16:42:52MEZ Muehlencord, Joern (joern.muehlencord)
- * Initial revision Member added to project
- * m:/MKS/ESP_Tools/shared/shared-network/shared-network.pj $Revision 1.6
- * 2013/09/05 07:14:33 jomu $fixed ldap search if group setup is not complete.
- * (1147451) $ $Revision 1.5 2013/09/04 15:07:26 jomu $fixed ldap search if
- * group setup is not complete. (1147451) $$
- *
- */