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 }