Hi J.L.,
In case you are interested, here is the latest patch I made against bacula 1.36.1-1. Unfortunately is send it just after another one has been proposed.
It adds support for a remote database by temporarily storring the password in the bacula .pgpass file. I have also updated the templates file to be more explicit about what is nedded and the potential security issues in the way I have had to do things.
As it contains some major modifications, you may not want to include what there is in it immediately, if at all.
However, by playing around with it, I noticed a couple of details :
-if the patch 10-grant_pgsql_privileges.patch is not applied, the bacula user will always have the same password to connect to the database. It might not be a very safe thing. That's why I reenabled it.
-It looks like debhelper does not like having a variable named db_password. It doesn't ask the question, and as a consequence the password would be the default one for any installation. Not a very safe thing again.
Anyway, feel free to use it, pick ideas in it, or ask me to modify things if you think it's worth it. If you want some help for other points in this package, please feel free to ask.
Regards, Regis
diff -urN bacula-1.36.1-1/debian/bacula-director-pgsql.config bacula-1.36.1/debian/bacula-director-pgsql.config --- bacula-1.36.1-1/debian/bacula-director-pgsql.config 2005-03-03 11:45:44.824294824 +0000 +++ bacula-1.36.1/debian/bacula-director-pgsql.config 2005-03-03 11:51:30.149797368 +0000 @@ -16,30 +16,20 @@ CATALOG="bacula" case "$1" in - configure) + configure | reconfigure) - # We leave out config for other hosts, for now + db_fget bacula-director-pgsql/pghost "seen" || true + if [ "$RET" = "true" -a "$1" = "configure" ]; then + exit 0 + fi + + db_beginblock + db_input medium bacula-director-pgsql/pghost || true +# db_input medium bacula-director-pgsql/db_user || true + db_input medium bacula-director-pgsql/pgpassword || true + db_endblock + db_go - #db_input medium bacula-director-pgsql/db_host || true - db_get bacula-director-pgsql/db_host - DB_HOST="$RET" - - #if [ $DB_HOST != "localhost" ]; then - # db_beginblock; - # db_input medium bacula-director-pgsql/db_user || true; - # db_input medium bacula-director-pgsql/db_password || true; - # db_endblock; - # db_go; - #else - ## localhost => just ask for password, so we don't - ## have to invent it - # user 'bacula', we use $HOME/.pgpass - db_input medium bacula-director-pgsql/db_password || true; - db_go; - #fi - - # This MUST be a clean installation -- no packaged version - # had PgSQL support before. db_input medium bacula-director-pgsql/create_tables || true db_go @@ -50,7 +40,8 @@ db_input medium bacula-director-pgsql/pgsql_root_username || true db_go - if [ "$DB_HOST" != "localhost" ]; then + db_get bacula-director-pgsql/pghost + if [ "$RET" != "localhost" ]; then # if localhost, we need not ask for the password :-) db_input medium bacula-director-pgsql/pgsql_root_password || true db_go @@ -61,83 +52,6 @@ db_go ;; - reconfigure) - - echo -# # We have all dependencies configured, so we can be a bit more clever :) -# # -# db_beginblock -# db_input medium bacula-director-pgsql/host || true -# db_input medium bacula-director-pgsql/user || true -# db_input medium bacula-director-pgsql/password || true -# db_endblock -# db_go - -# db_get bacula-director-pgsql/db_host; MYSQL_HOST="$RET"; -# db_get bacula-director-pgsql/db_user; MYSQL_USER="$RET"; -# db_get bacula-director-pgsql/db_password; MYSQL_PSWD="$RET"; -# if [ "$MYSQL_HOST" != "localhost" ]; then -# MYSQL_HOST_STRING="-h $MYSQL_HOST" -# fi -# if [ -z "$MYSQL_PSWD" ]; then -# MYSQL_CMD="mysql $MYSQL_HOST_STRING -u $MYSQL_USER"; -# else -# MYSQL_CMD="mysql $MYSQL_HOST_STRING -u $MYSQL_USER -p$MYSQL_PSWD"; -# fi - -# # if psql-client is not available, there's no point in -# # trying to configure ... yes? -# # test -x /usr/bin/mysql || exit 0 -# RESULT=`psql -t -A -F : -c '\q' bacula 2>&1`; -# case $RESULT in -# "") # No output => success, no tables -# db_input medium bacula-director-pgsql/create_tables || true -# db_go - -# db_get bacula-director-pgsql/create_tables; -# if [ "$RET" = "true" ]; then -# db_beginblock -# db_input medium bacula-director-pgsql/pgsql_root_username || true -# db_input medium bacula-director-pgsql/pgsql_root_password || true -# db_endblock -# db_go -# fi -# ;; - -# "psql: FATAL: * authentication failed for user"*) # Access denied -# #echo "ERROR: Access denied to PostgreSQL server!" >>/dev/fd/2 -# exit 0 -# ;; - -# "psql: FATAL: database * does not exist") #Unknown database -# db_input medium bacula-director-pgsql/create_tables || true -# db_go - -# db_get bacula-director-pgsql/create_tables; -# if [ "$RET" = "true" ]; then -# db_beginblock -# db_input medium bacula-director-pgsql/pgsql_root_username || true -# db_input medium bacula-director-pgsql/pgsql_root_password || true -# db_endblock -# db_go -# fi -# ;; - -# ERROR*|FATAL*) # unknown error! -# #echo "ERROR: PostgreSQL returned an unknown error code!" >>/dev/fd/2 -# exit 1 -# ;; - -# *) # output => some tables do exist -# #echo "Some tables exist in Database $CATALOG. Doing nothing." >> /dev/fd/2 -# exit 0 -# ;; -# esac -# -# db_input medium bacula-director-pgsql/remove_catalog_on_purge || true -# db_go - ;; - *) echo "config called with unknown argument \$1'" >&2 exit 0 diff -urN bacula-1.36.1-1/debian/bacula-director-pgsql.postinst bacula-1.36.1/debian/bacula-director-pgsql.postinst --- bacula-1.36.1-1/debian/bacula-director-pgsql.postinst 2005-03-03 11:45:44.843291936 +0000 +++ bacula-1.36.1/debian/bacula-director-pgsql.postinst 2005-03-03 11:51:55.048012264 +0000 @@ -32,158 +32,139 @@ ## Globals CATALOG=bacula PGSQL=/usr/bin/psql -MAKE_SQL_TABLES="/usr/share/bacula-director/make_pgsql_tables" -UPGRADE_SQL_DIR="/usr/share/bacula-director" -UPGRADE_TABLES="update_mysql_tables_7_to_8" +BACULA_SCRIPTS_DIR="/usr/share/bacula-director" +MAKE_SQL_TABLES="$BACULA_SCRIPTS_DIR/make_pgsql_tables" +GRANT_SQL_PRIVS="$BACULA_SCRIPTS_DIR/grant_pgsql_privileges" +POSTINST_COMMON="$BACULA_SCRIPTS_DIR/postinst-common" +UPGRADE_TABLES="$BACULA_SCRIPTS_DIR/update_mysql_tables_7_to_8" LOGDIR="/var/log/bacula" -GRANT_SQL_PRIVS="/usr/share/bacula-director/grant_pgsql_privileges" -POSTINST_COMMON="/usr/share/bacula-director/postinst-common" DEFCONFIG="/usr/share/bacula-common/defconfig" CFGFILE="/etc/bacula/bacula-dir.conf" + case "$1" in configure) - db_get bacula-director-pgsql/db_host || true - PGSQL_HOST="$RET" + db_get bacula-director-pgsql/pghost || true + DBHOST="$RET" + + db_get bacula-director-pgsql/pgsql_root_username || true + PGUSER="$RET" + export PGHOST PGUSER # default: "localhost" - if [ "$PGSQL_HOST" != "localhost" ]; then - PGSQL_HOST_STRING="-h $PGSQL_HOST" - export PGUSER=$DB_ADMIN - PGSQLCMD="/usr/bin/psql $PGSQL_HOST_STRING" - else # 'localhost' install - + if [ "$DBHOST" = "localhost" ]; then + if ! getent passwd $DB_ADMIN >/dev/null ; then echo -e "\nFATAL: the specified DB Administrator does not exist in 'passwd' databases" exit 1 fi - PGSQLCMD="su -s /bin/sh $dbadmin -c /usr/bin/psql" + SUPOSTGRES_CMD="su -s /bin/sh $PGUSER -c" + else + PGHOST="$DBHOST" + SUPOSTGRES_CMD="su -s /bin/sh $DBUSER -c" + + db_get bacula-director-pgsql/pgpassword || true + PGPASS="$RET" + + AUTHFILE=/var/lib/bacula/.pgpass + echo "$DBHOST:*:template1:$PGUSER:$PGPASS" > $AUTHFILE + chown bacula:root $AUTHFILE # reported by Shin-young Yune + chmod 0600 $AUTHFILE fi - - # Non-local setups are not yet supported. - # Patches are welcome !!! - echo -n "Checking DB connectivity..." - if ! $PGSQLCMD -l >/dev/null 2>&1; then - echo -e "\nFATAL: Could not connect to PostgreSQL server at $PGSQL_HOST" + if ! $SUPOSTGRES_CMD "$PGSQL -l" > /dev/null 2>&1; then + echo -e "\nFATAL: Could not connect to PostgreSQL server at $PGHOST" + rm -f $AUTHFILE exit 1 fi echo "Ok." - db_get bacula-director-pgsql/create_tables || true if [ "$RET" = "true" ]; then - if [ "$PGSQL_HOST" = "localhost" ]; then - # localhost, so we can go the easy way :-) - # We are already ·DB_ADMIN -- no need to worry about privileges - + DB_EXIST=`$SUPOSTGRES_CMD "$PGSQL -l" | grep $CATALOG` || true + if [ -z "$DB_EXIST" ]; then echo -n "Creating Catalog \"$CATALOG\" at 'localhost'... " - if ! eval $PGSQLCMD -d 'template1' -c "\"CREATE DATABASE bacula;\""; then + if ! $SUPOSTGRES_CMD "$PGSQL template1 -c \"CREATE DATABASE $CATALOG;\"" > /dev/null 2>&1; then echo -e "\nERROR: Database creation failed!"; + rm -f $AUTHFILE exit 1; fi echo "Ok." + fi - # Since it's insecure to pass the password to postgres as - # an environment variable - # (www.postgresql.org/docs/7.4/interactive/libpq-envars.html), - # the password is set in the $HOME/.pgpass file (for details check - # http://www.postgresql.org/docs/7.4/interactive/libpq-pgpass.html). - - # Create tables - echo -n "Creating tables ..." - if ! su -s /bin/sh $DB_ADMIN -c $MAKE_SQL_TABLES >/dev/null 2>&1 - then - echo -e "\nERROR: Table creation failed!" - exit 1 - fi - echo "Ok." + # Since it's insecure to pass the password to postgres as + # an environment variable + # (www.postgresql.org/docs/7.4/interactive/libpq-envars.html), + # the password is set in the $HOME/.pgpass file (for details check + # http://www.postgresql.org/docs/7.4/interactive/libpq-pgpass.html). + + # Create tables + echo -n "Creating tables ..." + if ! $SUPOSTGRES_CMD "$MAKE_SQL_TABLES" > /dev/null 2>&1 + then + echo -e "\nERROR: Table creation failed!" + rm -f $AUTHFILE + exit 1 + fi + echo "Ok." - # Grant privileges to (unprivileged user!) - db_get bacula-director-pgsql/db_user || true - DBUSER="$RET" - db_get bacula-director-pgsql/db_password || true - DBPASS="$RET" - - export DBUSER DBPASS - echo -n "Granting privileges ..." - if ! $GRANT_SQL_TABLES >/dev/null 2>&1 + if [ -n "$2" ] && dpkg --compare-versions "$2" lt "1.36.0"; then + rm -f $LOGDIR/upgrade.log + touch $LOGDIR/upgrade.log + + # On upgrade, unconditionally change Catalog + # patched upgrade script to use additional arguments on connection + echo -n "Upgrading Catalog to v8 ..." + if ! $UPGRADE_TABLES $PGSQL_HOST_STRING \ + > $LOGDIR/upgrade.log 2>&1 then - echo -e "\nERROR: Granting privileges failed!" + echo -e "\nERROR: Catalog upgrading failed! Check $LOGDIR/upgrade.log for details." + rm -f $AUTHFILE exit 1 - fi + fi echo "Ok." - fi # HOST == localhost - fi # bacula-director-pgsql/create_tables == "true" + + fi - if [ -n "$2" ] && dpkg --compare-versions "$2" lt "1.36.0"; then - rm -f $LOGDIR/upgrade.log - touch $LOGDIR/upgrade.log - - # On upgrade, unconditionally change Catalog - # patched upgrade script to use additional arguments on connection - echo -n "Upgrading Catalog to v8 ..." - if ! ${UPGRADE_SQL_DIR}/$UPGRADE_TABLES1 $PGSQL_HOST_STRING \ - > $LOGDIR/upgrade.log 2>&1 + #We must hardcode the user name if we want to use ident mode + #db_get bacula-director-pgsql/db_user || true + #DBUSER="$RET" + DBUSER="bacula" + db_get bacula-director-pgsql/pgpassword || true + DBPASS="$RET" + + export DBUSER DBPASS + echo -n "Granting privileges ..." + if ! $SUPOSTGRES_CMD "$GRANT_SQL_PRIVS" >/dev/null 2>&1 then - echo -e "\nERROR: Catalog upgrading failed! Check $LOGDIR/upgrade.log for details." - exit 1 - fi - echo "Ok." - - fi - - - #db_get bacula-director-pgsql/pgsql_root_username || true - #PGSQL_ROOT_USER="$RET" - #db_input high bacula-director-pgsql/pgsql_root_password || true - #PGSQL_ROOT_PSWD="$RET" - + echo -e "\nERROR: Granting privileges failed!" + rm -f $AUTHFILE + exit 1 + fi + echo "Ok." + fi # bacula-director-pgsql/create_tables == "true" + # Since it's insecure to pass the password to postgres as an environment # variable (www.postgresql.org/docs/7.4/interactive/libpq-envars.html), # the password is set in the $HOME/.pgpass file (check # http://www.postgresql.org/docs/7.4/interactive/libpq-pgpass.html). - # Grant privileges to (unprivileged user!) - #db_get bacula-director-pgsql/db_user || true - #DBUSER="$RET" - - # User hardwired to "Bacula" - - db_get bacula-director-pgsql/db_password || true - DBPASS="$RET" - - DBUSER="bacula" - export DBUSER DBPASS - echo -n "Granting privileges ..." - if ! $GRANT_SQL_PRIVS >/dev/null 2>&1 - then - echo -e "\nERROR: Granting privileges failed!" - exit 1 - fi - echo "Ok." - #AUTHFILE=`getent passwd bacula | cut -d ':' -f 6`/.pgpass AUTHFILE=/var/lib/bacula/.pgpass - echo "localhost:*:bacula:$DB_USER:$DB_PASS" > $AUTHFILE + echo "localhost:*:bacula:$DBUSER:$DBPASS" > $AUTHFILE chown bacula:root $AUTHFILE # reported by Shin-young Yune chmod 0600 $AUTHFILE - - #fi # bacula-director-pgsql/create_tables == "true" - - - # PreProcess configuration echo -n "Processing configuration ..." TARGET=$CFGFILE.dpkg-tmp - sed -e "s/dbname = bacula;/dbname = bacula; DB Address = $PGHOST;/" \ + sed -e "s/dbname = bacula;/dbname = bacula; DB Address = $DBHOST;/" \ -e "s/@db_user@/$DBUSER/" -e "s/@db_pswd@/$DBPASS/" \ $DEFCONFIG/bacula-dir.conf > $TARGET @@ -216,4 +197,6 @@ invoke-rc.d --quiet bacula-director start +#DEBHELPER# + exit 0 diff -urN bacula-1.36.1-1/debian/bacula-director-pgsql.postrm bacula-1.36.1/debian/bacula-director-pgsql.postrm --- bacula-1.36.1-1/debian/bacula-director-pgsql.postrm 2005-03-03 11:45:44.832293608 +0000 +++ bacula-1.36.1/debian/bacula-director-pgsql.postrm 2005-03-03 11:51:51.022624216 +0000 @@ -22,13 +22,52 @@ CONFFILE=/etc/bacula/bacula-dir.conf +CATALOG="bacula" +PGPASSFILE=/var/lib/bacula/.pgpass +DBUSER="bacula" case "$1" in purge) - rm -f $CONFFILE $CONFFILE.dist - # Drop Bacula's user privileges? Can't do - # Potentially, drop DB ... Can't do? - db_purge + rm -f $CONFFILE $CONFFILE.dist $PGPASSFILE + + db_get bacula-director-pgsql/pghost || true + DBHOST="$RET" + + db_get bacula-director-pgsql/pgsql_root_username || true + PGUSER="$RET" + + db_get bacula-director-pgsql/remove_catalog_on_purge || true + if [ "$RET" = "true" ]; then + + if [ "$DBHOST" = "localhost" ]; then + + if ! getent passwd $DB_ADMIN >/dev/null ; then + echo -e "\nFATAL: the specified DB Administrator does not exist in 'passwd' databases" + exit 1 + fi + SUPOSTGRES_CMD="su -s /bin/sh $PGUSER -c" + else + db_input medium bacula-director-pgsql/pgsql_root_password || true + db_go + PGPASS="$RET" + echo "$DBHOST:*:template1:$PGUSER:$PGPASS" > $PGPASSFILE + chown bacula:root $PGPASSFILE # reported by Shin-young Yune + chmod 0600 $PGPASSFILE + PGHOST="$DBHOST" + SUPOSTGRES_CMD="eval" + fi + + export PGHOST PGUSER + + echo -n "Destroying Catalog \"$CATALOG\" at 'localhost'... " + $SUPOSTGRES_CMD "/usr/bin/psql template1 -c \"DROP DATABASE $CATALOG;\"" || true + + echo -n "Destroying User bacula at 'localhost'... " + $SUPOSTGRES_CMD "/usr/bin/psql template1 -c \"DROP USER $DBUSER;\"" || true + + rm -f $PGPASSFILE + fi + ;; remove) diff -urN bacula-1.36.1-1/debian/bacula-director-pgsql.templates bacula-1.36.1/debian/bacula-director-pgsql.templates --- bacula-1.36.1-1/debian/bacula-director-pgsql.templates 2005-03-03 11:45:44.814296344 +0000 +++ bacula-1.36.1/debian/bacula-director-pgsql.templates 2005-03-03 11:51:38.980454904 +0000 @@ -1,17 +1,27 @@ -Template: bacula-director-pgsql/db_host +Template: bacula-director-pgsql/pghost Type: string _Default: localhost _Description: Where is the PostgreSQL server? Enter the host where the PostgreSQL server which is to hold Bacula's catalog is. + . + Warning: bacula cannot acces the database if the method includes "sameuser". + Note that it won't prevent this package from being installed, but the script + to start bacula-director will fail. Please make sure you modify your + /etc/postgres/pg_hba.conf accordingly. Template: bacula-director-pgsql/db_user Type: string _Default: bacula _Description: PostgreSQL username Please, enter the username which Bacula will use to connect to PostgreSQL. + . + Warning: bacula cannot acces the database if the method includes "sameuser". + Note that it won't prevent this package from being installed, but the script + to start bacula-director will fail. Please make sure you modify your + /etc/postgres/pg_hba.conf accordingly. -Template: bacula-director-pgsql/db_password +Template: bacula-director-pgsql/pgpassword Type: password _Default: NONE _Description: PostgreSQL password @@ -21,10 +31,12 @@ Type: boolean Default: true _Description: Create tables for Bacula's Catalog? - I have detected that the tables needed for Bacula's Catalog are missing - (this is probably a fresh install). Shall I create them now? + If the necessary catalog and tables do not already exist on the database + server, should they be created and the Bacula user be given access to them ? . - A PgSQL 'admin' username & password will be required. + A PgSQL 'admin' username & password will be required, which MUST have acces to + the 'template1' and 'bacula' catalogs. Please, make sure again your + /etc/postgres/pg_hba.conf file is correclty set up again. Template: bacula-director-pgsql/pgsql_root_username Type: string @@ -38,13 +50,16 @@ Type: password _Default: NONE _Description: PostgreSQL 'root' password - Please type the password for the username entered before. + Please type the password for the username entered before. This password will + be temporarily stored to /var/lib/bacula/.pgpass and removed at the end of + the installation. If for any reason the process was to fail, you should check + the content of this file. Template: bacula-director-pgsql/remove_catalog_on_purge Type: boolean Default: false -_Description: Remove Catalog on purge? - Shall I remove the Catalog from the PostgreSQL server at package purge time? +_Description: Remove Catalog and User on purge? + Shall I remove the Catalog and User from the PostgreSQL server ? This will free all the used space. . Warning: This is not undoable. Once you remove the catalog, you won't be diff -urN bacula-1.36.1-1/debian/rules bacula-1.36.1/debian/rules --- bacula-1.36.1-1/debian/rules 2005-03-03 11:45:44.821295280 +0000 +++ bacula-1.36.1/debian/rules 2005-03-03 11:52:10.990588624 +0000 @@ -196,13 +196,17 @@ $(RM) autoconf/Make.common Makefile $(RM) dbcheck bscan - # Unpatch everything. By [EMAIL PROTECTED] - #if test -f patch-stamp; then \ + # Unpatch everything. By [EMAIL PROTECTED] (at leat PostgreSQL) + if test -f patch-stamp; then \ + patch -p0 -R -i debian/patches/10-grant_pgsql_privileges.patch; \ + $(RM) patch-stamp; \ + fi + + #everything else is disabled # for p in `ls -1 debian/patches/*.patch | sort -r`; do \ # patch -p1 -i $$p; \ # done; \ - # $(RM) patch-stamp; \ - #fi + @@ -294,7 +298,8 @@ done -patch: +patch: patch-stamp +patch-stamp: chmod 755 debian/patches/btraceback chmod 755 debian/patches/fix_config debian/patches/fix_director chmod 755 debian/additions/bconsole @@ -304,6 +309,9 @@ # echo "Applying patch: $$pf"; \ # patch -p1 -s -i $$pf; \ #done; + #patch at least for PostgreSQL + patch -p0 -i debian/patches/10-grant_pgsql_privileges.patch + touch patch-stamp fixconfig: for f in bconsole.conf gnome-console.conf wx-console.conf \