diff --git a/src/de/superx/bin/LdapLockout.java b/src/de/superx/bin/LdapLockout.java new file mode 100644 index 0000000..d1bfa97 --- /dev/null +++ b/src/de/superx/bin/LdapLockout.java @@ -0,0 +1,69 @@ +package de.superx.bin; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; + +import de.memtext.util.GetOpts; +import de.superx.servlet.LdapPasswordChecker; +/** + * Klasse zum Sperren von Benutzern, die in LDAP gesperrt sind + * Erwartet Eintrag LdapLockoutFilter in superx_standalone_ldap.properties + * + * + */ +public class LdapLockout { + private static String usage = "Gebrauch: java de.superx.bin.LdapLockout -dbproperties=<> -ldapconfig=<>"; + public static void main(String[] args) { + GetOpts.setOpts(args); + String isdrin = GetOpts.isAllRequiredOptionsPresent("-dbproperties,-ldapconfig"); + if (isdrin != null) { + System.err.println("Folgende Optionen fehlen: " + isdrin); + System.err.println(usage); + System.exit(1); + } + + try { + File f = new File("LdapLockout.log"); + if (f.exists()) + { + f.delete(); + } + LdapPasswordChecker.setup(new File(GetOpts.getValue("-ldapconfig"))); + checkUsers(GetOpts.getValue("-dbproperties")); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void checkUsers(String dbpropfile) throws Exception { + SxConnection myConnection = new SxConnection(); + myConnection.setPropfile(dbpropfile); + Connection con = myConnection.getConnection(); + Statement stm = con.createStatement(); + ResultSet rs = stm.executeQuery("select benutzer from userinfo order by 1"); + PreparedStatement pst = con.prepareStatement( + "update userinfo set max_versuch=0,passwd_sha=null, gueltig_bis=today()-1, info='deaktiviert am '||today() where benutzer=? and max_versuch>0"); + LdapPasswordChecker ldappwc = new LdapPasswordChecker(); + while (rs.next()) { + String benutzer = rs.getString("benutzer"); + System.out.println("Pruefe Nutzer " + benutzer); + if (ldappwc.isUserLocked(benutzer)) { + System.out.println(" - Benutzer " + benutzer + " wird gesperrt"); + pst.clearParameters(); + pst.setString(1, benutzer); + pst.executeUpdate(); + } + } + rs.close(); + stm.close(); + pst.close(); + myConnection.close(); + ldappwc.closeServiceCtxForLockout(); + } +} diff --git a/src/de/superx/servlet/LdapPasswordChecker.java b/src/de/superx/servlet/LdapPasswordChecker.java index 3c371e6..20fc98f 100644 --- a/src/de/superx/servlet/LdapPasswordChecker.java +++ b/src/de/superx/servlet/LdapPasswordChecker.java @@ -37,6 +37,8 @@ public class LdapPasswordChecker { private static boolean hasLdapServiceUserDN = false; private static boolean wasSetupTestOK = false; private static boolean isStandaloneTest = false; + //wird nur für Lockout-Funktion benötigt + private DirContext serviceCtxForLockout = null; public static void main(String[] args) { isStandaloneTest = true; @@ -47,8 +49,8 @@ public class LdapPasswordChecker { try { setup(new File(args[0])); - LdapPasswordChecker lpc=new LdapPasswordChecker(); - lpc.isLdapPasswordOK(false, "default", args[1], args[2]); + LdapPasswordChecker lpc = new LdapPasswordChecker(); + lpc.isLdapPasswordOK(false, "default", args[1], args[2]); } catch (Exception e) { e.printStackTrace(); } @@ -63,12 +65,13 @@ public class LdapPasswordChecker { checkProperty(superxStandaloneLdapConfigFile, "LdapIdentifyingAttribute"); if (!StringUtils.isNullOrEmpty(props.getProperty("LdapServiceUserDN"))) { hasLdapServiceUserDN = true; - System.out.println(" LDAP Passwortkontrolle ServiceUser "+props.getProperty("LdapServiceUserDN")+" aktiviert"); + System.out.println( + " LDAP Passwortkontrolle ServiceUser " + props.getProperty("LdapServiceUserDN") + " aktiviert"); // momentan keine Prüfung ob LdapServiceUserPassword null oder Leerstring } // we don't need all attributes, just let it get the identifying one LdapPasswordChecker.attributeFilter[0] = props.getProperty("LdapIdentifyingAttribute"); - + // Verbindungstest wirft Exception bei Fehler boolean isJustSetupTest = true; String mandantenIDNichtRelevant = "default"; @@ -92,6 +95,27 @@ public class LdapPasswordChecker { " Property \"" + name + "\" ist in Datei " + superxStandaloneLdapConfigFile + " nicht konfiguiert"); } + public boolean isUserLocked(String benutzer) throws Exception { + if (props.size() == 0) + throw new IllegalStateException( + "LDAP Passwordchecker nicht konfiguiert, setup Methode muss vorher aufgerufen werden"); + boolean result = false; + //lazy init, da viele User abgefragt werden + if (serviceCtxForLockout == null) { + serviceCtxForLockout = initContext(); + } + + NamingEnumeration searchResults = searchForUserLockedStatus(serviceCtxForLockout, benutzer); + if (searchResults.hasMoreElements()) { + result = true; + } + return result; + } + + public void closeServiceCtxForLockout() throws NamingException { + serviceCtxForLockout.close(); + } + /** * Prüft via LDAP ob ein Passwort OK ist * @@ -113,7 +137,7 @@ public class LdapPasswordChecker { try { serviceCtx = initContext(); if (isStandaloneTest) { - System.out.println("Reine Kontrolle, ob User "+username+ " existiert"); + System.out.println("Reine Kontrolle, ob User " + username + " existiert"); } NamingEnumeration searchResults = searchForUser(serviceCtx, username); if (!isJustSetupTest) { @@ -139,29 +163,42 @@ public class LdapPasswordChecker { } } - //System.out.println(new Date().getTime() - start.getTime()); + // System.out.println(new Date().getTime() - start.getTime()); } return false; } - private NamingEnumeration searchForUser(DirContext serviceCtx, String username) + private NamingEnumeration searchForUserLockedStatus(DirContext serviceCtx, String username) throws NamingException { SearchControls sc = new SearchControls(); sc.setReturningAttributes(attributeFilter); sc.setSearchScope(SearchControls.SUBTREE_SCOPE); // use a search filter to find only the user we want to authenticate - String searchFilter = ""; - if (props.getProperty("LdapSearchFilter")!=null) + if (StringUtils.isNullOrEmpty(props.getProperty("LdapLockoutFilter"))) { - searchFilter=StringUtils.replace(props.getProperty("LdapSearchFilter"),"${0}", username ); + throw new NamingException("LdapLockoutFilter ist nicht definiert"); } - else - { - searchFilter="(" + props.getProperty("LdapIdentifyingAttribute") + "=" + username + ")"; + String searchFilter = StringUtils.replace(props.getProperty("LdapLockoutFilter"), "${0}", username); + + return serviceCtx.search(props.getProperty("LdapBase"), searchFilter, sc); + } + + private NamingEnumeration searchForUser(DirContext serviceCtx, String username) + throws NamingException { + SearchControls sc = new SearchControls(); + sc.setReturningAttributes(attributeFilter); + sc.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // use a search filter to find only the user we want to authenticate + String searchFilter = ""; + if (props.getProperty("LdapSearchFilter") != null) { + searchFilter = StringUtils.replace(props.getProperty("LdapSearchFilter"), "${0}", username); + } else { + searchFilter = "(" + props.getProperty("LdapIdentifyingAttribute") + "=" + username + ")"; } - //searchFilter="(&(uid="+username+")(mail=boyle@ldap.forumsys.com))"; - + // searchFilter="(&(uid="+username+")(mail=boyle@ldap.forumsys.com))"; + return serviceCtx.search(props.getProperty("LdapBase"), searchFilter, sc); } @@ -181,8 +218,10 @@ public class LdapPasswordChecker { SearchResult result = searchResults.next(); String distinguishedName = result.getNameInNamespace(); if (isStandaloneTest) { - System.out.println(" User "+username +" gefunden - distingushedName(DN/nameInNamespace):"+distinguishedName); - System.out.println(" versuche Authentifizierung für "+distinguishedName+" mit eingegebenen Passwort"); + System.out.println( + " User " + username + " gefunden - distingushedName(DN/nameInNamespace):" + distinguishedName); + System.out + .println(" versuche Authentifizierung für " + distinguishedName + " mit eingegebenen Passwort"); } // attempt another authentication, now with the user, throws exception if // problem diff --git a/superx/WEB-INF/conf/edustore/db/bin/sx_ldap_lockout.x b/superx/WEB-INF/conf/edustore/db/bin/sx_ldap_lockout.x new file mode 100755 index 0000000..16fc1d0 --- /dev/null +++ b/superx/WEB-INF/conf/edustore/db/bin/sx_ldap_lockout.x @@ -0,0 +1,6 @@ +#!/bin/bash +if [ "$1" = "" ] + then echo "Aufruf: sx_ldap_lockout.x Pfad/zu/db.properties pfad/zu/superx_standalone_ldap.properties" + exit 0 +fi +java -cp "$JDBC_CLASSPATH" de.superx.bin.LdapLockout -dbproperties:$1 -ldapconfig:$2