#!/bin/bash
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
# This script demonstrates using LDAP for Arvados user authentication.
#
# It configures arvados controller in a docker container, optionally
--name=${ldapctr} \
osixia/openldap:1.3.0
docker logs --follow ${ldapctr} 2>$debug >$debug &
-ldaphostport=$(docker port ${ldapctr} 389/tcp)
-ldapport=${ldaphostport##*:}
+ldaphostports=$(docker port ${ldapctr} 389/tcp)
+ldapport=${ldaphostports##*:}
ldapurl="ldap://${hostname}:${ldapport}"
passwordhash="$(docker exec -i ${ldapctr} slappasswd -s "secret")"
Connection:
client_encoding: utf8
host: ${hostname}
+ port: "${pgport}"
dbname: arvados_test
user: arvados
password: insecure_arvados_test
setup_pam_ldap="apt update && DEBIAN_FRONTEND=noninteractive apt install -y ldap-utils libpam-ldap && pam-auth-update --package /usr/share/pam-configs/ldap"
cat >>"${tmpdir}/zzzzz.yml" <<EOF
Login:
- PAM: true
- # Without this magic PAMDefaultEmailDomain, inserted users would
- # prevent subsequent database/reset from working (see
- # database_controller.rb).
- PAMDefaultEmailDomain: example.com
+ PAM:
+ Enable: true
+ # Without this specific DefaultEmailDomain, inserted users
+ # would prevent subsequent database/reset from working (see
+ # database_controller.rb).
+ DefaultEmailDomain: example.com
EOF
;;
ldap)
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
-shadowMax: 180
+shadowMax: -1
shadowMin: 1
shadowWarning: 7
shadowLastChange: 10701
gidNumber: 11111
homeDirectory: /home/foo-bar
userPassword: ${passwordhash}
+
+dn: uid=expired,dc=example,dc=org
+uid: expired
+cn: "Exp Ired"
+givenName: Exp
+sn: Ired
+mail: expired@example.com
+objectClass: inetOrgPerson
+objectClass: posixAccount
+objectClass: top
+objectClass: shadowAccount
+shadowMax: 180
+shadowMin: 1
+shadowWarning: 7
+shadowLastChange: 10701
+loginShell: /bin/bash
+uidNumber: 11112
+gidNumber: 11111
+homeDirectory: /home/expired
+userPassword: ${passwordhash}
EOF
echo >&2 "Adding example user entry user=foo-bar pass=secret (retrying until server comes up)"
debian:10 \
bash -c "${setup_pam_ldap:-true} && arvados-server controller"
docker logs --follow ${ctrlctr} 2>$debug >$debug &
-ctrlhostport=$(docker port ${ctrlctr} 9999/tcp)
+ctrlhostports=$(docker port ${ctrlctr} 9999/tcp)
+ctrlport=${ctrlhostports##*:}
echo >&2 "Waiting for arvados controller to come up..."
for f in $(seq 1 20); do
- if curl -s "http://${ctrlhostport}/arvados/v1/config" >/dev/null; then
+ if curl -s "http://0.0.0.0:${ctrlport}/arvados/v1/config" >/dev/null; then
break
else
sleep 1
echo -n >&2 .
done
echo >&2
-echo >&2 "Arvados controller is up at http://${ctrlhostport}"
+echo >&2 "Arvados controller is up at http://0.0.0.0:${ctrlport}"
check_contains() {
resp="${1}"
set +x
echo >&2 "Testing authentication failure"
-resp="$(set -x; curl -s --include -d username=foo-bar -d password=nosecret "http://${ctrlhostport}/arvados/v1/users/authenticate" | tee $debug)"
+resp="$(set -x; curl -s --include -d username=foo-bar -d password=nosecret "http://0.0.0.0:${ctrlport}/arvados/v1/users/authenticate" | tee $debug)"
check_contains "${resp}" "HTTP/1.1 401"
if [[ "${config_method}" = ldap ]]; then
check_contains "${resp}" '{"errors":["LDAP: Authentication failure (with username \"foo-bar\" and password)"]}'
check_contains "${resp}" '{"errors":["PAM: Authentication failure (with username \"foo-bar\" and password)"]}'
fi
+if [[ "${config_method}" = pam ]]; then
+ echo >&2 "Testing expired credentials"
+ resp="$(set -x; curl -s --include -d username=expired -d password=secret "http://0.0.0.0:${ctrlport}/arvados/v1/users/authenticate" | tee $debug)"
+ check_contains "${resp}" "HTTP/1.1 401"
+ check_contains "${resp}" '{"errors":["PAM: Authentication failure; \"You are required to change your LDAP password immediately.\""]}'
+fi
+
echo >&2 "Testing authentication success"
-resp="$(set -x; curl -s --include -d username=foo-bar -d password=secret "http://${ctrlhostport}/arvados/v1/users/authenticate" | tee $debug)"
+resp="$(set -x; curl -s --include -d username=foo-bar -d password=secret "http://0.0.0.0:${ctrlport}/arvados/v1/users/authenticate" | tee $debug)"
check_contains "${resp}" "HTTP/1.1 200"
check_contains "${resp}" '"api_token":"'
check_contains "${resp}" '"scopes":["all"]'
token="v2/$uuid/$secret"
echo >&2 "New token is ${token}"
-resp="$(set -x; curl -s --include -H "Authorization: Bearer ${token}" "http://${ctrlhostport}/arvados/v1/users/current" | tee $debug)"
+resp="$(set -x; curl -s --include -H "Authorization: Bearer ${token}" "http://0.0.0.0:${ctrlport}/arvados/v1/users/current" | tee $debug)"
check_contains "${resp}" "HTTP/1.1 200"
if [[ "${config_method}" = ldap ]]; then
# user fields come from LDAP attributes