added support for locked users
This commit is contained in:
@ -1,10 +1,17 @@
|
||||
package de.muehlencord.shared.network.ldap;
|
||||
|
||||
import de.muehlencord.shared.util.DateUtil;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.BitSet;
|
||||
import java.util.Date;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Connection to ldap server to searh by different values
|
||||
@ -13,6 +20,8 @@ import javax.naming.directory.SearchResult;
|
||||
*/
|
||||
public class LDAPSearch {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LDAPSearch.class);
|
||||
|
||||
/**
|
||||
* the ldap connection to use
|
||||
*/
|
||||
@ -26,22 +35,17 @@ public class LDAPSearch {
|
||||
* Creates a new instance of a ldap search.
|
||||
*
|
||||
* <p>
|
||||
* Important: <br> 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) </p>
|
||||
* Important: <br> 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) </p>
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
* <pre>
|
||||
* -Djavax.net.ssl.trustStore=/path/to/truststore.keystore
|
||||
* </pre> </p>
|
||||
*
|
||||
* @param url the url of the ldap server to connect to like
|
||||
* <code>ldap://ldapserver.your.domain:389</code>
|
||||
* @param searchBase the search base to use - e.g.
|
||||
* <code>DC=wincor-nixdorf,DC=com</code>
|
||||
* @param url the url of the ldap server to connect to like <code>ldap://ldapserver.your.domain:389</code>
|
||||
* @param searchBase the search base to use - e.g. <code>DC=wincor-nixdorf,DC=com</code>
|
||||
* @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.
|
||||
*
|
||||
* <p>
|
||||
* Important: <br> 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) </p>
|
||||
* Important: <br> 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) </p>
|
||||
*
|
||||
* <p>
|
||||
* 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
|
||||
* <pre>
|
||||
* -Djavax.net.ssl.trustStore=/path/to/truststore.keystore
|
||||
* </pre> </p>
|
||||
*
|
||||
* @param authentication the authentification type to use -e.g. "SIMPLE"
|
||||
* @param url the url of the ldap server to connect to like
|
||||
* <code>ldap://ldapserver.your.domain:389</code>
|
||||
* @param securityProtoco the security protocol to use - e.g. SIMPLE
|
||||
* @param searchBase the search base to use - e.g.
|
||||
* <code>DC=wincor-nixdorf,DC=com</code>
|
||||
* @param url the url of the ldap server to connect to like <code>ldap://ldapserver.your.domain:389</code>
|
||||
* @param securityProtocol the security protocol to use - e.g. SIMPLE
|
||||
* @param searchBase the search base to use - e.g. <code>DC=wincor-nixdorf,DC=com</code>
|
||||
* @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,6 +227,8 @@ 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());
|
||||
@ -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) $$
|
||||
*
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user