Skip to content

Commit

Permalink
Merge pull request #218 from joergsteffens/dev/joergs/master/systemte…
Browse files Browse the repository at this point in the history
…st-bconsole-pam

add bconsole-pam systemtest
  • Loading branch information
joergsteffens committed Jul 11, 2019
2 parents 9798577 + 2310a00 commit 5d70986
Show file tree
Hide file tree
Showing 32 changed files with 484 additions and 18 deletions.
2 changes: 2 additions & 0 deletions core/cmake/BareosFindAllLibraries.cmake
Expand Up @@ -75,6 +75,8 @@ BareosFindLibrary("gtest")
BareosFindLibrary("gtest_main")
BareosFindLibrary("gmock")

BareosFindLibrary("pam_wrapper")

if (${HAVE_CAP})
SET(HAVE_LIBCAP 1)
endif()
Expand Down
12 changes: 10 additions & 2 deletions core/src/console/console.cc
Expand Up @@ -1071,25 +1071,33 @@ int main(int argc, char* argv[])
BStringList response_args;

UA_sock = ConnectToDirector(jcr, heart_beat, response_args, response_id);
if (!UA_sock) { return 1; }
if (!UA_sock) {
ConsoleOutput(_("Failed to connect to Director. Giving up.\n"));
TerminateConsole(0);
return 1;
}

UA_sock->OutputCipherMessageString(ConsoleOutput);

if (response_id == kMessageIdPamRequired) {
#if defined(HAVE_PAM)
if (!ExaminePamAuthentication(use_pam_credentials_file,
pam_credentials_filename)) {
ConsoleOutput(_("PAM authentication failed. Giving up.\n"));
TerminateConsole(0);
return 1;
}
response_args.clear();
if (!UA_sock->ReceiveAndEvaluateResponseMessage(response_id,
response_args)) {
ConsoleOutput(_("PAM authentication failed. Giving up.\n"));
TerminateConsole(0);
return 1;
}
#else
Dmsg0(200, "This console does not have the pam feature\n");
ConsoleOutput(
_("PAM authentication requested by Director, however this console "
"does not have this feature. Giving up.\n"));
TerminateConsole(0);
return 1;
#endif /* HAVE_PAM */
Expand Down
2 changes: 1 addition & 1 deletion docs/manuals/source/Configuration/Console.rst
Expand Up @@ -155,7 +155,7 @@ The following is an example of a :file:`bconsole.conf` file that can access seve
Console {
Name = restricted-user
Password = "RUPASSWORD"
Director = MyDirector
Director = bareos-dir
}
Console {
Expand Down
34 changes: 20 additions & 14 deletions docs/manuals/source/TasksAndConcepts/PAM.rst
Expand Up @@ -61,50 +61,56 @@ To enable PAM authentication two systems have to be configured. The PAM module i

PAM Module
^^^^^^^^^^
This is depending on the operating system and on the used pam module. For details read the manuals. The name of the service that has to be registered is "bareos".
This is depending on the operating system and on the used pam module. For details read the manuals. The name of the service that has to be registered is **bareos**.

Fedora 28 example: :

.. code-block:: ini
.. code-block:: bareosconfig
:caption: :file:`/etc/pam.d/bareos`
# check authorization
auth required pam_unix.so
.. warning::

The |dir| runs as user **bareos**. However, some PAM modules require more priviliges. E.g. **pam_unix** requires access to the file :file:`/etc/shadow`, which is normally not permitted. Make sure you verify your system accordingly.

Bareos Console
^^^^^^^^^^^^^^
For PAM authentication a dedicated named console is used. Set the directive UsePamAuthentication=yes in the regarding Director-Console resource:

.. code-block:: ini
.. code-block:: bareosconfig
:caption: :file:`bareos-dir.d/console/pam-console.conf`
Console {
Name = "PamConsole"
Password = "Secretpassword"
UsePamAuthentication = yes
Name = "PamConsole"
Password = "Secretpassword"
UsePamAuthentication = yes
}
In the dedicated |bconsole| config use name and password according as to the |dir|:

.. code-block:: ini
.. code-block:: bareosconfig
:caption: :file:`bconsole.conf`
Director {
...
}
Console {
Name = "PamConsole"
Password = "Secretpassword"
Name = "PamConsole"
Password = "Secretpassword"
}
PAM User
^^^^^^^^
Users have limited access to commands and jobs. Therefore the appropriate rights should also be granted to PAM users. This is an example of a User resource (Bareos Director Configuration):

.. code-block:: ini
:caption: :file:`bareos-dir.d/console/pam-user.conf`
.. code-block:: bareosconfig
:caption: :file:`bareos-dir.d/user/a-pam-user.conf`
User {
Name = "a-pam-user"
Password = "" #unsed because authenticated by PAM
Password = "" # unsed because authenticated by PAM
CommandACL = status, .status
JobACL = *all*
}
21 changes: 20 additions & 1 deletion systemtests/CMakeLists.txt
Expand Up @@ -157,7 +157,6 @@ foreach(CURRENT_FILE ${ALL_FILES})
# MESSAGE(STATUS "moved ${scripts}/${TARGET_FILE}")
endforeach()


set(tests_dir ${PROJECT_BINARY_DIR}/tests)
set(SYSTEM_TESTS
backup-bareos-test
Expand All @@ -170,6 +169,26 @@ set(SYSTEM_TESTS
copy-remote-bscan
)

IF(PAM_WRAPPER_LIBRARIES)
find_program(PAMTESTER pamtester)
IF(PAMTESTER)
set(ENV{PAM_WRAPPER_LIBRARIES} "${PAM_WRAPPER_LIBRARIES}")
execute_process(
COMMAND "${CMAKE_BINARY_DIR}/systemtests/tests/bconsole-pam/bin/check_pam_exec_available.sh"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/systemtests/tests/bconsole-pam/"
RESULT_VARIABLE PAM_EXEC_AVAILABLE_RC
)
IF(${PAM_EXEC_AVAILABLE_RC} EQUAL "0")
set(PAM_EXEC_FOUND TRUE)
list(APPEND SYSTEM_TESTS "bconsole-pam")
ENDIF()

MESSAGE( STATUS "PAM_EXEC_FOUND: " ${PAM_EXEC_FOUND} )

ENDIF()
ENDIF()


set(BASEPORT 42001)

foreach(TEST_NAME ${SYSTEM_TESTS})
Expand Down
2 changes: 2 additions & 0 deletions systemtests/environment.in
Expand Up @@ -54,3 +54,5 @@ export tmp
export db_name=@db_name@
export db_password=@db_password@
export db_user=@db_user@

export PAM_WRAPPER_LIBRARIES=@PAM_WRAPPER_LIBRARIES@
33 changes: 33 additions & 0 deletions systemtests/tests/bconsole-pam/bin/check_pam_exec_available.sh
@@ -0,0 +1,33 @@
#!/bin/sh

#
# Verify that our test pam configuration works.
# It uses
# * pam_wrapper to redirect PAM to our test environemnt, using a specific service file
# * pamtester to test PAM without the need to run Bareos
# * pam_exec.so is defined in the bareos PAM service file.
# It is configured to accept all logins where USERNAME = PASSWORD.
#

set -e
set -u

export PAM_WRAPPER=1
export PAM_WRAPPER_SERVICE_DIR=etc/pam.d/bareos

if ! [ -e "${PAM_WRAPPER_SERVICE_DIR}" ]; then
echo "PAM service file ${PAM_WRAPPER_SERVICE_DIR} not found"
exit 1
fi

# DEBUG
#export PAM_WRAPPER_DEBUGLEVEL=4

# PAM_WRAPPER creates extra environments in /tmp/pam.*/

# PAM_WRAPPER_LIBRARIES will be set my cmake
USERNAME="user"
PASSWORD="user"
echo "$PASSWORD" | LD_PRELOAD=${PAM_WRAPPER_LIBRARIES} pamtester bareos "$USERNAME" authenticate

exit $?
75 changes: 75 additions & 0 deletions systemtests/tests/bconsole-pam/bin/pam_exec_check.sh
@@ -0,0 +1,75 @@
#!/bin/sh

# auth optional pam_exec.so expose_authtok debug log=/tmp/pam.log /usr/bin/sc_pam_wlan.sh

# called by:
# auth optional pam_exec.so expose_authtok /usr/bin/sc_pam_wlan.sh

# pam_exec options:
# debug
# expose_authtok
# During authentication the calling command can read the password from stdin(3).
# (PAM_TYPE=auth only)
# log=file
# The output of the command is appended to file
# type=type
# Only run the command if the module type matches the given type.
# stdout
# Per default the output of the executed command is written to /dev/null.
# With this option, the stdout output of the executed command is redirected
# to the calling application.
# It's in the responsibility of this application what happens with the output.
# The log option is ignored.
# quiet
# Per default pam_exec.so will echo the exit status of the external command
# if it fails. Specifying this option will suppress the message.
# seteuid
# Per default pam_exec.so will execute the external command
# with the real user ID of the calling process.
# Specifying this option means the command is run with the effective user ID.

# PAM_TYPE:
# "auth"
# ...
# "open_session"
# "close_session"

RC_OK=0
RC_SKIP=1
RC_NOK=2

echo "$0"
#echo "current user: $USER ($UID)"

if [ "$PAM_TYPE" != "auth" ]; then
echo "only pam type auth supported, not $PAM_TYPE"
exit $RC_SKIP
fi

echo "PAM settings:"
echo "User: $PAM_USER"
echo "Ruser: $PAM_RUSER"
echo "Rhost: $PAM_RHOST"
echo "Service: $PAM_SERVICE"
echo "TTY: $PAM_TTY"

USERNAME="$PAM_USER"
# This does not work in PAM environment
# if [ -z "$PAM_USER" ]; then
# read -p "PE Login: " USERNAME
# fi


read -p "PE Passwort: " PASSWORD


if [ "$USERNAME" = "$PASSWORD" ]; then
echo "grant access for $USERNAME"
RC=$RC_OK
else
echo "deny access for $USERNAME"
RC=$RC_NOK
fi

exit $RC

@@ -0,0 +1,8 @@
Catalog {
Name = MyCatalog
#dbdriver = "@DEFAULT_DB_TYPE@"
dbdriver = "XXX_REPLACE_WITH_DATABASE_DRIVER_XXX"
dbname = "@db_name@"
dbuser = "@db_user@"
dbpassword = "@db_password@"
}
@@ -0,0 +1,7 @@
Client {
Name = bareos-fd
Description = "Client resource of the Director itself."
Address = localhost
Password = "@fd_password@" # password for FileDaemon
FD PORT = @fd_port@
}
@@ -0,0 +1,6 @@
Console {
Name = "PamConsole"
Password = "secret"
UsePamAuthentication = yes
}

@@ -0,0 +1,27 @@
Director { # define myself
Name = bareos-dir
QueryFile = "@scriptdir@/query.sql"
Maximum Concurrent Jobs = 10
Password = "@dir_password@" # Console password
Messages = Daemon
Auditing = yes

# Enable the Heartbeat if you experience connection losses
# (eg. because of your router or firewall configuration).
# Additionally the Heartbeat can be enabled in bareos-sd and bareos-fd.
#
# Heartbeat Interval = 1 min

# remove comment in next line to load dynamic backends from specified directory
Backend Directory = @backenddir@

# remove comment from "Plugin Directory" to load plugins from specified directory.
# if "Plugin Names" is defined, only the specified plugins will be loaded,
# otherwise all director plugins (*-dir.so) from the "Plugin Directory".
#
# Plugin Directory = "@plugindir@"
# Plugin Names = ""
Working Directory = "@working_dir@"
Pid Directory = "@piddir@"
DirPort = @dir_port@
}
@@ -0,0 +1,11 @@
FileSet {
Name = "Catalog"
Description = "Backup the catalog dump and Bareos configuration files."
Include {
Options {
signature = MD5
}
File = "@working_dir@/@db_name@.sql" # database dump
File = "@confdir@" # configuration
}
}
@@ -0,0 +1,11 @@
FileSet {
Name = "SelfTest"
Description = "fileset just to backup some files for selftest"
Include {
Options {
Signature = MD5 # calculate md5 checksum per file
}
#File = "@sbindir@"
File=<@tmpdir@/file-list
}
}
@@ -0,0 +1,11 @@
Job {
Name = "RestoreFiles"
Description = "Standard Restore template. Only one such job is needed for all standard Jobs/Clients/Storage ..."
Type = Restore
Client = bareos-fd
FileSet = SelfTest
Storage = File
Pool = Incremental
Messages = Standard
Where = @tmp@/bareos-restores
}
@@ -0,0 +1,5 @@
Job {
Name = "backup-bareos-fd"
JobDefs = "DefaultJob"
Client = "bareos-fd"
}
@@ -0,0 +1,15 @@
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
Client = bareos-fd
FileSet = "SelfTest"
Storage = File
Messages = Standard
Pool = Incremental
Priority = 10
Write Bootstrap = "@working_dir@/%c.bsr"
Full Backup Pool = Full # write Full Backups into "Full" Pool
Differential Backup Pool = Differential # write Diff Backups into "Differential" Pool
Incremental Backup Pool = Incremental # write Incr Backups into "Incremental" Pool
}
@@ -0,0 +1,7 @@
Messages {
Name = Daemon
Description = "Message delivery for daemon messages (no job)."
console = all, !skipped, !saved, !audit
append = "@logdir@/bareos.log" = all, !skipped, !audit
append = "@logdir@/bareos-audit.log" = audit
}

0 comments on commit 5d70986

Please sign in to comment.