#!/bin/bash
set -e
set -o pipefail
set -u
#
# This test tests the bconsole against the bareos-dir using PAM authentication.
#
# Requires:
# on Debian following packages must be installed:
#   libpam-modules (for pam_exec.so),
#   libpam-wrapper,
#   pamtester
# On Fedora, the names are similar: pam, pam-wrapper, pamtester.
#
# If they are not available, the test will be disabled by cmake.
#
# PAM is configured to accept all users where USERNAME = PASSWORD.
#
# Interactive PAM login in bconsole does not work,
# as the configured PAM module does not ask for the username.
# However, providing the PAM credentials to bconsole as file (bconsole -p CREDENTIALS_FILE) does work.
#
TestName="$(basename "$(pwd)")"
export TestName

#shellcheck source=../environment.in
. ./environment

JobName=backup-bareos-fd
#shellcheck source=../scripts/functions
. "${rscripts}"/functions
"${rscripts}"/cleanup
"${rscripts}"/setup


start_test

export PAM_WRAPPER=1
export PAM_WRAPPER_SERVICE_DIR=${current_test_directory}/etc/pam.d/bareos
# PAM_WRAPPER creates extra environments in /tmp/pam.*/
# However, these are removed when bareos-dir daemonized.
# This settings keeps them all.
# Other workaround: don't let bareos-dir daemonize itself,
# but use foreground and ampersand (-f and &)
#export PAM_WRAPPER_KEEP_DIR=1

# PAM_WRAPPER_LIBRARIES has to set be cmake

# check if we linked to libasan, if so we'll need to preload that library first
libasan="$(ldd "${BAREOS_DIRECTOR_BINARY}" | awk '/libasan.so/ { print $3 }')"

preload_libs="${PAM_WRAPPER_LIBRARIES}"
if [ -n "$libasan" ]; then
  preload_libs="${libasan}:${preload_libs}"
fi

output=/dev/null
BAREOS_DIR_OPTIONS=""
if is_debug; then
    export PAM_WRAPPER_DEBUGLEVEL=4
    BAREOS_DIR_OPTIONS="-d 200"
    output=/dev/stdout
    LD_PRELOAD="${preload_libs}" "${BAREOS_DIRECTOR_BINARY}" -c "${conf}" -f "${BAREOS_DIR_OPTIONS}" >$output 2>&1 &
else
    LD_PRELOAD="${preload_libs}" "${BAREOS_DIRECTOR_BINARY}" -c "${conf}" -f                       >$output 2>&1 &
fi

sleep 1

cat <<END_OF_DATA >"$tmp"/bconcmds
@$out $tmp/log1.out
status director
quit
END_OF_DATA

if ! "${BAREOS_BCONSOLE_BINARY}" -c "${conf}" -p etc/user1.cred < "$tmp"/bconcmds >"${tmp}"/log1.out 2>"${tmp}"/err1.out; then
  cat "${tmp}"/log1.out
  cat "${tmp}"/err1.out
  set_error "Failed to login as user user1."
  exit 1
fi

if ! grep -q "Running Jobs:" "${tmp}"/log1.out; then
  cat "${tmp}"/log1.out
  set_error "Unexpected output in user1 session."
  exit 1
fi

print_debug "OK: login as user1 succeeded."

if "${BAREOS_BCONSOLE_BINARY}" -c "${conf}" -p etc/user2.cred < "$tmp"/bconcmds >"${tmp}"/log2.out 2>"${tmp}"/err2.out; then
  cat "${tmp}"/log2.out
  cat "${tmp}"/err2.out
  set_error "Login as user user2 succeeded. This should NOT happen."
  exit 1
fi

print_debug "OK: login as user2 failed."

cat <<END_OF_DATA >"$tmp"/bconcmds-add-user
@$out $tmp/log3.out
configure add user name=user3 description="script configured user" profile=operator
reload
quit
END_OF_DATA

## create user3
if ! "${BAREOS_BCONSOLE_BINARY}" -c "${conf}" -p etc/user1.cred < "$tmp"/bconcmds-add-user >"${tmp}"/log4.out 2>"${tmp}"/err4.out; then
  cat "${tmp}"/log4.out
  cat "${tmp}"/err4.out
  set_error "Failed to login as user user1 and add new user3."
  exit 1
fi

cat <<END_OF_DATA >"$tmp"/bconcmds-user3
@$out $tmp/log5.out
status director
quit
END_OF_DATA

##login as user 3
if ! "${BAREOS_BCONSOLE_BINARY}" -c "${conf}" -p etc/user3.cred < "$tmp"/bconcmds-user3 >"${tmp}"/log6.out 2>"${tmp}"/err6.out; then
  cat "${tmp}"/log6.out
  cat "${tmp}"/err6.out
  set_error "Failed to login as user user3."
  exit 1
fi

if ! grep -q "Running Jobs:" "${tmp}"/log5.out; then
  cat "${tmp}"/log5.out
  set_error "Unexpected output in user3 session."
  exit 1
fi

if "${BAREOS_BCONSOLE_BINARY}" -c "${conf}" -p etc/user4locked.cred < "$tmp"/bconcmds >"${tmp}"/log7.out 2>"${tmp}"/err7.out; then
  cat "${tmp}"/log7.out
  cat "${tmp}"/err7.out
  set_error "Login as user user4locked succeeded. This should NOT happen."
  exit 1
fi

print_debug "OK: login as user4locked failed."


if ! ${rscripts}/bareos-ctl-dir status >/dev/null; then
  set_error "Director does not run anymore. This should not happen."
  exit 1
fi


stop_bareos > $output 2>&1

end_test
