backuppc: new package
authorCarsten Wolff <redacted>
Sun, 8 Apr 2018 20:09:48 +0000 (22:09 +0200)
committerCarsten Wolff <redacted>
Wed, 7 Aug 2019 22:29:11 +0000 (00:29 +0200)
Signed-off-by: Carsten Wolff <redacted>
Reviewed-by: Rosen Penev <redacted>
admin/backuppc/Makefile [new file with mode: 0644]
admin/backuppc/files/backuppc.init [new file with mode: 0644]
admin/backuppc/files/backuppc.upgrade [new file with mode: 0644]
admin/backuppc/files/fixup-config-pl.patch [new file with mode: 0644]
admin/backuppc/files/setuidwrapper.c [new file with mode: 0644]
admin/backuppc/patches/001-debian-fixes.patch [new file with mode: 0644]

diff --git a/admin/backuppc/Makefile b/admin/backuppc/Makefile
new file mode 100644 (file)
index 0000000..56b62ec
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright (C) 2018 OpenWrt
+#
+# Ideas used from the backuppc packaging in Debian GNU/Linux
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=backuppc
+PKG_VERSION:=3.3.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=BackupPC-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/backuppc
+PKG_HASH:=fbade2c8d8039297e826a75d2c39d5ac9a6f66e0c84c0cf8c4cef0bcf64d2152
+PKG_BUILD_DIR:=$(BUILD_DIR)/BackupPC-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Carsten Wolff <carsten@wolffcarsten.de>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/backuppc
+  SECTION:=admin
+  CATEGORY:=Administration
+  TITLE:=high-performance, enterprise-grade system for backing up PCs
+  URL:=https://sourceforge.net/projects/backuppc/
+  DEPENDS:=+perl +perl-www +perl-cgi +perlbase-digest +perlbase-compress +perlbase-archive +perlbase-data +perlbase-storable +perlbase-getopt +perl-file-rsyncp +openssh-client +tar +bzip2 +samba36-client +rsync +iputils-ping
+endef
+
+define Package/backuppc/description
+  BackupPC is a disk based backup system featuring a clever pooling scheme and
+  compression to minimize disk storage and disk I/O. It can use SMB, rsync or tar
+  to access the clients without any additional client software and offers a
+  powerful http/cgi user interface.
+endef
+
+define Build/Configure
+       true
+endef
+
+define Build/Compile
+       $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS) -Wall -o $(PKG_BUILD_DIR)/BackupPC_Admin ./files/setuidwrapper.c
+endef
+
+define Package/backuppc/install
+       $(INSTALL_DIR) $(strip $(1))/etc/init.d
+       $(INSTALL_BIN) ./files/backuppc.init $(strip $(1))/etc/init.d/backuppc
+       cd $(PKG_BUILD_DIR) && ./configure.pl --batch --html-dir-url=/backuppc/ \
+           --html-dir=/www/backuppc/ --cgi-dir=/www/cgi-bin/ --no-fhs --uid-ignore \
+           --dest-dir=$(strip $(1)) --install-dir /usr/share/backuppc \
+           --hostname=XXXXXX --data-dir=/data/backuppc --log-dir=/data/backuppc/log \
+           --bin-path perl=/usr/bin/perl --bin-path tar=/bin/tar \
+           --bin-path smbclient=/usr/sbin/smbclient --bin-path nmblookup=/usr/sbin/nmblookup \
+           --bin-path rsync=/usr/bin/rsync --bin-path ping=/usr/bin/ping --bin-path df=/bin/df \
+           --bin-path ssh=/usr/bin/ssh --bin-path gzip=/bin/gzip \
+           --bin-path sendmail=/usr/sbin/sendmail --bin-path bzip2=/usr/bin/bzip2
+       $(INSTALL_DIR) $(strip $(1))/usr/share/backuppc/conf
+       chmod 755 $(strip $(1))/data
+       mv $(strip $(1))/data/backuppc/conf/config.pl $(strip $(1))/usr/share/backuppc/conf/config.pl
+       patch --no-backup-if-mismatch $(strip $(1))/usr/share/backuppc/conf/config.pl ./files/fixup-config-pl.patch
+       mv $(strip $(1))/www/cgi-bin/BackupPC_Admin $(strip $(1))/usr/share/backuppc/bin/BackupPC_Admin_real
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/BackupPC_Admin $(strip $(1))/www/cgi-bin/BackupPC_Admin
+       $(INSTALL_DIR) $(strip $(1))/lib/upgrade/keep.d
+       $(INSTALL_DATA) files/backuppc.upgrade  $(strip $(1))/lib/upgrade/keep.d/backuppc
+endef
+
+$(eval $(call BuildPackage,backuppc))
diff --git a/admin/backuppc/files/backuppc.init b/admin/backuppc/files/backuppc.init
new file mode 100644 (file)
index 0000000..7f5253d
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/sh /etc/rc.common
+
+. /lib/functions.sh
+
+START=95
+STOP=10
+
+USE_PROCD=1
+BACKUPPC_BIN="/usr/share/backuppc/bin/BackupPC"
+BACKUPPC_USER=backuppc
+
+# it would be better if it was possible to do this at install time, but we
+# can't, because in case of an openwrt image bundled with backuppc, all
+# ownerships other than root are lost.
+preconfigure() {
+    # create backuppc group and user if needed
+    if ! group_exists backuppc; then
+        group_add backuppc 864
+    fi
+    if ! user_exists backuppc; then
+        user_add backuppc 864 864 "BackupPC user" /data/backuppc /bin/sh
+    fi
+    # install default config if none exists, yet
+    if [ ! -e /data/backuppc/conf/config.pl ]; then
+        cp /usr/share/backuppc/conf/config.pl /data/backuppc/conf/config.pl
+    fi
+    # ensure proper ownerships and rights
+    chown backuppc:backuppc /data/backuppc /data/backuppc/* \
+                            /www/cgi-bin/BackupPC_Admin
+    chmod 750 /data/backuppc /data/backuppc/*
+    chmod 755 /usr/share/backuppc/bin/BackupPC_Admin_real
+    # The CGI needs to be world-executable, because uhttpd-cgi.c:386 checks
+    # for exactly that. We don't want that, but can't avoid it, currently.
+    chmod 6751 /www/cgi-bin/BackupPC_Admin
+    chown -R :backuppc /data/backuppc/conf
+    chmod 2770 /data/backuppc/conf
+    # protect webinterface with a random password by default
+    if [ -x /usr/sbin/uhttpd ] && ! grep -q backuppc /etc/httpd.conf >/dev/null 2>&1; then
+        PASS=$(perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..8)')
+        PASSHASH=$(/usr/sbin/uhttpd -m "${PASS}")
+        echo "/cgi-bin/BackupPC_Admin:backuppc:${PASSHASH}" >> /etc/httpd.conf
+        uci set uhttpd.main.config=/etc/httpd.conf
+        /etc/init.d/uhttpd restart
+        # inform user
+        echo
+        echo "To protect access to the backuppc web interface, HTTP basic authentication in"
+        echo "uhttpd for http://$(/sbin/uci get "system.@system[0].hostname")/cgi-bin/BackupPC_Admin has been configured:"
+        echo "user: backuppc"
+        echo "pass: ${PASS}"
+        echo
+        echo "It is also recommended to follow the steps in"
+        echo "https://wiki.openwrt.org/doc/uci/uhttpd#securing_uhttpd"
+        echo "to secure access to uhttpd."
+    fi
+}
+
+start_service() {
+    # don't run preconfigure steps if called during image build
+    if [ -z "${IPKG_INSTROOT}" ]; then
+        preconfigure
+    fi
+    procd_open_instance
+    procd_set_param user $BACKUPPC_USER
+    procd_set_param reload_signal 1
+    procd_set_param command $BACKUPPC_BIN
+}
diff --git a/admin/backuppc/files/backuppc.upgrade b/admin/backuppc/files/backuppc.upgrade
new file mode 100644 (file)
index 0000000..aaf016f
--- /dev/null
@@ -0,0 +1,2 @@
+/etc/httpd.conf
+/data/backuppc/conf/
diff --git a/admin/backuppc/files/fixup-config-pl.patch b/admin/backuppc/files/fixup-config-pl.patch
new file mode 100644 (file)
index 0000000..2fa567c
--- /dev/null
@@ -0,0 +1,67 @@
+--- config.pl  2018-03-11 09:30:28.000000000 +0100
++++ config.pl.new      2018-04-05 08:40:29.180000000 +0200
+@@ -41,7 +41,10 @@
+ #
+ # Host name on which the BackupPC server is running.
+ #
+-$Conf{ServerHost} = 'XXXXXX';
++$ENV{'PATH'} = '/bin:/usr/bin';
++delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
++$Conf{ServerHost} = $ENV{'HOSTNAME'};
++chomp($Conf{ServerHost});
+ #
+ # TCP port number on which the BackupPC server listens for and accepts
+@@ -223,7 +226,7 @@
+ #
+ # Full path to various commands for archiving
+ #
+-$Conf{SplitPath} = '/usr/bin/split';
++$Conf{SplitPath} = '/usr/bin/split' if ( -x '/usr/bin/split' );
+ $Conf{ParPath}   = '';
+ $Conf{CatPath}   = '/bin/cat';
+ $Conf{GzipPath}  = '/bin/gzip';
+@@ -1572,7 +1575,7 @@
+ # Full path for ssh. Security caution: normal users should not
+ # allowed to write to this file or directory.
+ #
+-$Conf{SshPath} = '/usr/bin/ssh';
++$Conf{SshPath} = '/usr/bin/ssh' if ( -x '/usr/bin/ssh' );
+ #
+ # Full path for nmblookup. Security caution: normal users should not
+@@ -1874,7 +1877,7 @@
+ # Full path to the sendmail command.  Security caution: normal users
+ # should not allowed to write to this file or directory.
+ #
+-$Conf{SendmailPath} = '/usr/sbin/sendmail';
++$Conf{SendmailPath} = '/usr/sbin/sendmail' if ( -x '/usr/sbin/sendmail' );
+ #
+ # Minimum period between consecutive emails to a single user.
+@@ -2028,13 +2031,13 @@
+ #    $Conf{CgiAdminUsers}     = 'craig celia';
+ #    --> administrative users are only craig and celia'.
+ #
+-$Conf{CgiAdminUserGroup} = '';
+-$Conf{CgiAdminUsers}     = '';
++$Conf{CgiAdminUserGroup} = 'backuppc';
++$Conf{CgiAdminUsers}     = 'backuppc';
+ #
+ # URL of the BackupPC_Admin CGI script.  Used for email messages.
+ #
+-$Conf{CgiURL} = 'http://XXXXXX/cgi-bin//BackupPC_Admin';
++$Conf{CgiURL} = 'http://' . $Conf{ServerHost} . '/cgi-bin//BackupPC_Admin';
+ #   
+ # Language to use.  See lib/BackupPC/Lang for the list of supported
+@@ -2076,7 +2079,7 @@
+ # dates (MM/DD), a value of 2 uses full YYYY-MM-DD format, and zero
+ # for international dates (DD/MM).
+ #
+-$Conf{CgiDateFormatMMDD} = 1;
++$Conf{CgiDateFormatMMDD} = 2;
+ #
+ # If set, the complete list of hosts appears in the left navigation
diff --git a/admin/backuppc/files/setuidwrapper.c b/admin/backuppc/files/setuidwrapper.c
new file mode 100644 (file)
index 0000000..b4496ff
--- /dev/null
@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+int main(int argc, char* argv[])
+{
+    execv("/usr/share/backuppc/bin/BackupPC_Admin_real", argv);
+    return 0;
+}
+
diff --git a/admin/backuppc/patches/001-debian-fixes.patch b/admin/backuppc/patches/001-debian-fixes.patch
new file mode 100644 (file)
index 0000000..3701755
--- /dev/null
@@ -0,0 +1,99 @@
+--- a/bin/BackupPC_archive     2017-01-26 02:31:24.000000000 +0100
++++ b/bin/BackupPC_archive     2018-04-05 21:11:14.428000000 +0200
+@@ -299,7 +299,7 @@
+     if ( $NeedPostCmd ) {
+         UserCommandRun("ArchivePostUserCmd");
+         if ( $? && $Conf{UserCmdCheckStatus} ) {
+-            $stat{hostError} = "RestorePreUserCmd returned error status $?";
++            $stat{hostError} = "ArchivePostUserCmd returned error status $?";
+             $stat{xferOK} = 0;
+         }
+     }
+--- a/bin/BackupPC_dump        2017-01-26 02:31:24.000000000 +0100
++++ b/bin/BackupPC_dump        2018-04-05 21:12:23.640000000 +0200
+@@ -1067,7 +1067,7 @@
+           # Send ALRMs to BackupPC_tarExtract if we are using it
+           #
+           if ( $tarPid > 0 ) {
+-              kill($bpc->sigName2num("ARLM"), $tarPid);
++              kill($bpc->sigName2num("ALRM"), $tarPid);
+           }
+           #
+--- a/configure.pl     2017-01-26 02:31:24.000000000 +0100
++++ b/configure.pl     2018-04-05 21:39:24.668000000 +0200
+@@ -333,7 +333,10 @@
+                                  $Conf{BackupPCUser} || "backuppc",
+                                  "backuppc-user");
+     if ( $opts{"set-perms"} ) {
+-        ($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
++        #($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
++        $name = 'backuppc';
++        $Uid=`id -u`;
++        $Gid=`id -g`;
+         last if ( $name ne "" );
+         print <<EOF;
+@@ -800,6 +803,7 @@
+ #
+ # Figure out sensible arguments for the ping command
+ #
++$Conf{PingArgs} = '-c 1 $host';
+ if ( defined($Conf{PingArgs}) ) {
+     $Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs};
+ } elsif ( !defined($Conf{PingCmd}) ) {
+--- a/lib/BackupPC/CGI/View.pm 2017-01-26 02:31:24.000000000 +0100
++++ b/lib/BackupPC/CGI/View.pm 2018-04-05 21:46:22.664000000 +0200
+@@ -46,7 +46,7 @@
+     my $compress = 0;
+     my $fh;
+     my $host = $In{host};
+-    my $num  = $In{num};
++    my $num  = ${EscHTML($In{num})};
+     my $type = $In{type};
+     my $linkHosts = 0;
+     my($file, $comment);
+@@ -136,6 +136,10 @@
+                   }
+                   $s =~ s/[\n\r]+//g;
+                   if ( $s =~ /smb: \\>/
++                          || $s =~ /^tar:\d+\s/
++                          || $s =~ /^  NTLMSSP_/
++                          || $s =~ /^GENSEC backend /
++                          || $s =~ /^doing parameter /
+                           || $s =~ /^\s*(\d+) \(\s*\d+\.\d kb\/s\) (.*)$/
+                           || $s =~ /^tar: dumped \d+ files/
+                           || $s =~ /^\s*added interface/i
+--- a/lib/BackupPC/Lib.pm      2017-01-26 02:31:24.000000000 +0100
++++ b/lib/BackupPC/Lib.pm      2018-04-05 21:48:38.048000000 +0200
+@@ -512,7 +512,8 @@
+     }
+     if ( $IODirentOk ) {
+         @entries = sort({ $a->{inode} <=> $b->{inode} } readdirent($fh));
+-        map { $_->{type} = 0 + $_->{type} } @entries;   # make type numeric
++        #map { $_->{type} = 0 + $_->{type} } @entries;   # make type numeric
++        map { $_->{type} = 0 + $_->{type}; $_->{type} = undef if ($_->{type} eq BPC_DT_UNKNOWN); } @entries;   # make type numeric, unset unknown types
+     } else {
+         @entries = map { { name => $_} } readdir($fh);
+     }
+--- a/lib/BackupPC/Xfer/Smb.pm 2017-01-26 02:31:24.000000000 +0100
++++ b/lib/BackupPC/Xfer/Smb.pm 2018-04-05 21:57:16.616000000 +0200
+@@ -219,7 +219,7 @@
+         #
+         # MAKSYM 14082016: The next regex will never match on Samba-4.3, as
+         # smbclient doesn't produce output required; keeping it for older Sambas
+-        if ( /^\s*(-?\d+) \(\s*\d+[.,]\d kb\/s\) (.*)$/ ) {
++        if ( /^\s*(-?\d+) \(\s*\d+[.,]\d kb\/s\) (.*)$/ || /^tar:(\d+)\s+\+\+\+ (.*)$/ ) {
+             my $sambaFileSize = $1;
+             my $pcFileName    = $2;
+             (my $fileName = $pcFileName) =~ s/\\/\//g;
+@@ -281,6 +281,9 @@
+         } elsif ( /smb: \\>/
+                 || /^\s*tar:\d+/ # MAKSYM 14082016: ignoring 2 more Samba-4.3 specific lines
+                 || /^\s*WARNING:/i
++                || /^  NTLMSSP_/
++                || /^GENSEC backend /
++                || /^doing parameter /
+                 || /^\s*added interface/i
+                 || /^\s*tarmode is now/i
+                 || /^\s*Total bytes written/i
git clone https://git.99rst.org/PROJECT