diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0777d7740fbf2b5e2ac0c71142405377dfa9af1e..4816d89dd2cb332191014d7d52aa068ba5a7d326 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,14 +11,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Changed
 
+* `misc/pam_authentication/ldap.conf` is not used for configuring the
+  `ldap_authentication.sh` script anymore.
+  Use `misc/pam_authentication/ldap.env` instead and view the documentation
+  inside the file itself for more information.
+
 ### Deprecated
 
 ### Removed
 
 ### Fixed
 
+* `ldap_authentication.sh <username>` failed on every attempt when used in
+  combination with OpenLDAP with default configuration.
+* `ldap_authentication.sh` allowed empty and even wrong passwords when used in
+  combination with MS Active Directory when AD is configured to allow binding
+  with an empty password.
+
 ### Security
 
+* `ldap_authentication.sh` allowed empty and even wrong passwords when used in
+  combination with MS Active Directory when AD is configured to allow binding
+  with an empty password. This is only relevant for non-default configurations
+  of the `PAM.pam_script` option in the `usersources.ini`.
 
 ## [0.7.2] - 2022-03-25
 (Timm Fitschen)
diff --git a/caosdb-webui b/caosdb-webui
index e6788d0380bdaf02d43498347616e6f3c4195663..406d2b935e8b8e834dce613928120472e3ec777d 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit e6788d0380bdaf02d43498347616e6f3c4195663
+Subproject commit 406d2b935e8b8e834dce613928120472e3ec777d
diff --git a/misc/pam_authentication/ldap.conf b/misc/pam_authentication/ldap.conf
deleted file mode 100644
index 664dd7c97524242fdb1ea7015bbc0e26c087b062..0000000000000000000000000000000000000000
--- a/misc/pam_authentication/ldap.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file is sourced by the LDAP authentication script
-
-# Set the ldap server here.
-# LDAP_SERVER="example.com"
-
-# Set the ldap domain here. This is used to generate a fully qualified
-# user name: <USER>@$LDAP_DOMAIN
-# LDAP_DOMAIN="example.com"
diff --git a/misc/pam_authentication/ldap.env b/misc/pam_authentication/ldap.env
new file mode 100644
index 0000000000000000000000000000000000000000..6067400cb2f0d965b2b85a7ac08f3b35117864c5
--- /dev/null
+++ b/misc/pam_authentication/ldap.env
@@ -0,0 +1,50 @@
+# ldap.env - This file is sourced by the LDAP authentication script.
+#
+# Please see https://linux.die.net/man/5/ldap.conf for more client
+# configuration variables.
+
+# REQUIRED - Set the ldap server here,
+export LDAPURI="ldap[s]://<ldap-service>[:<port>]"
+
+# REQUIRED - Set the base domain here. This is used to generate a fully
+# qualified user name, a Distinguished Name (DN), with the BIND_DN_PATTERN:
+export USER_BASE="dc=example,dc=org" # for actual LDAP servers
+#export USER_BASE="example.org" # for MS Active Directory
+
+# The BIND_DN_PATTERN is used to construct the DN from the USER_NAME and the
+# USER_BASE. Be sure to surround it with single quotation marks "'" because the
+# variables inside are to be expanded by the script. Defaults to the first
+#export BIND_DN_PATTERN='cn=${USER_NAME},${USER_BASE}' # for actual LDAP servers.
+#export BIND_DN_PATTERN='${USER_NAME}@${USER_BASE}' # for MS Active Directory
+
+# The WHO_AM_I_PATTERN is used to construct the expected representation of the
+# bound user account. Normal LDAP servers return "dn:<dn>" but MS Active
+# Directory chooses to return "u:<domain>\<user_name>" instead. Be sure to
+# surround it with single quotation marks "'" because the variables inside are
+# to be expanded by the script. Defaults to the first.
+#export WHO_AM_I_PATTERN='dn:cn=${USER_NAME},${USER_BASE}' # for actual LDAP
+                                                           # servers.
+#export WHO_AM_I_PATTERN='u:<domain>\\${USER_NAME}' # for MS Active Directory.
+                                                    # Mind the double back-slash.
+
+# TLS SETTINGS
+
+# Specifies what checks to perform on server certificates in a TLS session, if
+# any. Defaults to "hard" which means that a successful TLS-certificate check
+# is necessary.
+#export LDAPTLS_REQCERT=never
+#export LDAPTLS_REQCERT=allow
+#export LDAPTLS_REQCERT=try
+#export LDAPTLS_REQCERT=hard
+
+# In some cases there is no need for specifying the TLS certificates here, e.g.
+# when they are installed system-wide. If that does not work, use these
+# variables:
+
+# Specifies the file that contains certificates for all of the Certificate
+# Authorities the client will recognize.
+#export LDAPTLS_CACERT="<filename>"
+
+# Specifies the path of a directory that contains Certificate Authority
+# certificates in separate individual files.
+#export LDAPTLS_CACERTDIR="<path>"
diff --git a/misc/pam_authentication/ldap_authentication.sh b/misc/pam_authentication/ldap_authentication.sh
index 1b86b8e1783399e2c43b92981a43789accb21e7d..e58b5caa3e518a386169b37d1723b76418570162 100755
--- a/misc/pam_authentication/ldap_authentication.sh
+++ b/misc/pam_authentication/ldap_authentication.sh
@@ -24,37 +24,44 @@
 # Try to authenticate a user ($1) via LDAP, either via stdin or a password file ($2, if given).
 
 [[ "$#" == "1" || "$#" == "2" ]] || {
-    echo "Call this script as: $0 <user> [<password file>]"
+    echo "Call this script as: $0 <user> [-|<password file>]"
     exit 1
 }
 
-# set LDAP_SERVER here
-# e.g. `LDAP_SERVER=example.com`
-exe_dir=$(dirname $0)
-. "$exe_dir/"ldap.conf
+# Load all LDAP client settings
+exe_dir=$(dirname "$0")
+. "$exe_dir/ldap.env"
+LDAPTLS_REQCERT="${LDAP_TLS_REQCERT:-hard}"
+BIND_DN_PATTERN="${BIND_DN_PATTERN:-"cn=\${USER_NAME},\${USER_BASE}"}"
+WHO_AM_I_PATTERN="${WHO_AM_I_PATTERN:-"dn:cn=\${USER_NAME},\${USER_BASE}"}"
 
 # If the second argument is empty or "-", take password from stdin, else use the argument as a file.
 testpw() {
-    username="${1}@${LDAP_DOMAIN}"
+    local USER_NAME bind_dn who_am_i pwfile pwargs result
+
+    # cn is case-insensitive https://ldapwiki.com/wiki/Distinguished%20Name%20Case%20Sensitivity
+    USER_NAME="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
+
+    bind_dn="$(eval "echo \"$BIND_DN_PATTERN\"")"
+    who_am_i="$(eval "echo \"$WHO_AM_I_PATTERN\"")"
+
     pwfile="$2"
-    pwargs=("-w" "$pwfile")
-    if [[ $pwfile == "-" ]] ; then
+    pwargs=("-y" "$pwfile")
+    if [ "$pwfile" = "-" ] ; then
+        pwargs=("-W")
+    elif [ -z "$pwfile" ] ; then
         pwargs=("-W")
     fi
 
-    export LDAPTLS_REQCERT=ALLOW
-    if timeout 5s ldapwhoami -x -H "ldaps://$LDAP_SERVER" -D "$username" "${pwargs[@]}"; then
+    result="$(ldapwhoami -o "nettimeout=10" -x -D "$bind_dn" "${pwargs[@]}")"
+    if [ "$?" -ne "0" ] ; then
+        return 1
+    elif [ "$result" = "$who_am_i" ] ; then
         return 0
-    else
-        ret_code="$?"
     fi
-
-    # Possibly try a second time
-    if [[ "$ret_code" != "124" ]] ; then
-        return "$ret_code"
-    fi
-
-    ldapwhoami -x -H "ldaps://$LDAP_SERVER" -D "$username" "${pwargs[@]}"
+    echo "result : $result"
+    echo "pattern: $who_am_i"
+    return 1
 
 }