diff --git a/lib.php b/lib.php
index 58d8a74..8a8c707 100644
--- a/lib.php
+++ b/lib.php
@@ -168,6 +168,8 @@ function db_load_enum($table, $column) {
             WHERE table_name=? AND column_name=?";
     $sth = $dbh->prepare($sql);
     $sth->execute([$table, $column]);
+    // Für PHP < 7.4
+    // return array_map(function($x) { return trim($x, "'"); }, explode(',', $sth->fetchColumn()));
     return array_map(fn($x) => trim($x, "'"), explode(',', $sth->fetchColumn()));
 }
 
diff --git a/login.php b/login.php
index add5f87..9073824 100644
--- a/login.php
+++ b/login.php
@@ -22,6 +22,36 @@ $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
 
 include("lib.php"); // only for get_language from browser. TODO: simplify
 
+function check_ldap_bind($user_name, $user_pass) {
+    global $config_ldap_host;
+    global $config_ldap_port;
+    global $config_ldap_base_dn;
+    global $config_ldap_bind_dn;
+    global $config_ldap_bind_pass;
+    global $config_ldap_login_attr;
+    $ldap_conn = NULL;
+    foreach ($config_ldap_host as $server) {
+        if ($ldap_conn = ldap_connect($server, $config_ldap_port)) {
+            if ($res = ldap_bind($ldap_conn, $config_ldap_bind_dn, $config_ldap_bind_pass)) {
+                ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0);
+                ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
+                $filter = "(&(objectClass=user)($config_ldap_login_attr=$user_name))";
+                $res = ldap_search($ldap_conn, $config_ldap_base_dn, $filter, ['dn']);
+                if ($res) {
+                    $info = ldap_get_entries($ldap_conn, $res);
+                    $user_dn = $info[0]['dn'];
+                    $res = ldap_bind($ldap_conn, $user_dn, $user_pass);
+                    if ($res) {
+                        return TRUE;
+                    }
+                }
+            }
+            return FALSE;
+        }
+    }
+    return FALSE;
+}
+
 function user_login ($user_name, $user_pass) {
     global $dbh;
 
@@ -47,20 +77,28 @@ function user_login ($user_name, $user_pass) {
         return FALSE;
     }
 
-    if (strcmp(md5($user_pass), rtrim($user->user_pass)) != 0) {
-        // password does not match with md5, check if new hash matches
-        // For future expansion: $pwd_peppered = hash_hmac('sha256', $user_pass, $config_pepper);
-        if (! password_verify($user_pass, $user->user_pass)) {
+    if ($user->user_realm == 'ldap') {
+        // check LDAP auth
+        if (! check_ldap_bind($user_name, $user_pass)) {
             return FALSE;
         }
-    } else {
-        // md5 match but outdated. rewrite with new algo
-        $sth = $dbh->prepare("UPDATE user SET user_pass=? WHERE user_id=?");
-        $newhash = password_hash($user_pass, PASSWORD_BCRYPT);
-        $sth->execute([$newhash, $user->user_id]);
+        // TODO sync LDAP data to local
+    { else {
+        // compare local passwords
+        if (strcmp(md5($user_pass), rtrim($user->user_pass)) != 0) {
+            // password does not match with md5, check if new hash matches
+            // For future expansion: $pwd_peppered = hash_hmac('sha256', $user_pass, $config_pepper);
+            if (! password_verify($user_pass, $user->user_pass)) {
+                return FALSE;
+            }
+        } else {
+            // md5 match but outdated. rewrite with new algo
+            $sth = $dbh->prepare("UPDATE user SET user_pass=? WHERE user_id=?");
+            $newhash = password_hash($user_pass, PASSWORD_BCRYPT);
+            $sth->execute([$newhash, $user->user_id]);
+        }
     }
 
-
     // all ok: user is logged in, register session data
     $_SESSION['suser_id'] = $user->user_id;
     $_SESSION['suser_realm'] = $user->user_realm;