Group :: Archiving/Backup
RPM: burp
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: burp-2.3.16-alt3.patch
Download
Download
.gear/burp.init | 102 +++++++++++++++++++++++++++++++
.gear/burp.service | 10 +++
.gear/burp.spec | 131 ++++++++++++++++++++++++++++++++++++++++
.gear/rules | 3 +
.gear/tags/list | 1 +
.gear/test-burp.sh | 71 ++++++++++++++++++++++
.gear/test-client.conf | 23 +++++++
.gear/test-server.conf | 33 ++++++++++
.gear/upstream/remotes | 3 +
Makefile.am | 6 +-
android/burp_ca | 1 -
configs/certs/CA/CA.cnf.in | 1 -
configs/certs/CA/burp_ca.bat.in | 1 -
configs/certs/CA/burp_ca.in | 3 -
configs/client/burp.conf.in | 9 ++-
configure.ac | 14 +++++
manpages/burp.8.in | 3 +
src/conf.c | 2 +
src/conf.h | 3 +
src/handy.c | 77 +++++++++++++++++------
src/handy.h | 12 +++-
src/prog.c | 10 ++-
src/server/child.c | 2 +-
utest/test_conf.c | 1 +
24 files changed, 492 insertions(+), 30 deletions(-)
diff --git a/.gear/burp.init b/.gear/burp.init
new file mode 100755
index 00000000..e5c41cae
--- /dev/null
+++ b/.gear/burp.init
@@ -0,0 +1,102 @@
+#! /bin/sh
+#
+# burp init file distributed with brup package
+# author: bassu@phi9.com
+#
+# burp-server Start burp server
+#
+# chkconfig: - 08 92
+# description: Burp backup server
+#
+# processname: burp
+# config: /etc/burp/burp-server.conf
+# pidfile: /var/run/burp.server.pid
+#
+### BEGIN INIT INFO
+# Provides: burp-server
+# Required-Start: $network $syslog $local_fs
+# Required-Stop: $network $syslog $local_fs
+# Default-Start:
+# Default-Stop:
+# Description: Burp backup server daemon
+# Short-Description: Burp backup server
+### END INIT INFO
+
+. /etc/init.d/functions
+
+RETVAL=0
+prog=burp
+burp=${BURP-/usr/sbin/burp}
+pidfile=${PIDFILE-/var/run/burp.server.pid}
+lockfile=${LOCKFILE-/var/lock/subsys/burp}
+conffile=${CONFFILE-/etc/burp/burp-server.conf}
+
+start () {
+ status -p ${pidfile} ${burp} &>/dev/null && { echo "$prog is already running"; exit 1; }
+ echo -n $"Starting $prog: "
+ start_daemon ${burp} -c ${conffile}
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch ${lockfile}
+}
+stop () {
+ echo -n $"Stopping $prog: "
+ stop_daemon ${prog}
+ RETVAL=$?
+ echo
+ if [ $RETVAL -eq 0 ] ; then
+ rm -f ${lockfile} ${pidfile}
+ fi
+}
+
+restart () {
+ stop
+ start
+}
+
+reload () {
+ echo -n $"Reloading $prog: "
+ stop_daemon -p ${pidfile} ${prog} -HUP
+ RETVAL=$?
+ echo
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status -p ${pidfile} ${burp}
+ RETVAL=$?
+ ;;
+ restart)
+ restart
+ ;;
+ reload)
+ reload
+ ;;
+ condstop)
+ if [ -e "$lockfile" ]; then
+ stop
+ fi
+ ;;
+ condrestart)
+ if [ -e "$lockfile" ]; then
+ restart
+ fi
+ ;;
+ condreload)
+ if [ -e "$lockfile" ]; then
+ reload
+ fi
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|status|restart|reload|condstop|condrestart|condreload}"
+ RETVAL=2
+ ;;
+esac
+
+exit $RETVAL
diff --git a/.gear/burp.service b/.gear/burp.service
new file mode 100644
index 00000000..92ba4989
--- /dev/null
+++ b/.gear/burp.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Burp backup server
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/sbin/burp -c /etc/burp/burp-server.conf
+
+[Install]
+WantedBy=multi-user.target
diff --git a/.gear/burp.spec b/.gear/burp.spec
new file mode 100644
index 00000000..d823e174
--- /dev/null
+++ b/.gear/burp.spec
@@ -0,0 +1,131 @@
+Name: burp
+Version: 2.3.16
+Release: alt3
+
+Summary: Burp is a network-based backup and restore program
+License: AGPL-3.0 and BSD and GPLv2+ and LGPLv2+
+Group: Archiving/Backup
+Url: https://burp.grke.org/
+
+# https://github.com/grke/burp.git master
+Source: %{name}-%{version}.tar
+Patch: %{name}-%{version}-%{release}.patch
+
+BuildRequires: libtool
+BuildRequires: librsync-devel
+BuildRequires: zlib-devel
+BuildRequires: openssl-devel
+BuildRequires: libncurses-devel
+BuildRequires: libacl-devel
+BuildRequires: libuthash-devel
+BuildRequires: libyajl-devel
+BuildRequires: check libcheck-devel
+BuildRequires: libcap-devel
+BuildRequires: openssl
+
+BuildRequires: rpm-macros-intro-conflicts
+%add_findreq_skiplist %_datadir/%name/scripts/*
+
+%description
+Burp is a network backup and restore program, using client and server.
+It uses librsync in order to save network traffic and to save on the
+amount of space that is used by each backup.
+
+%prep
+%setup
+%patch -p1
+
+%build
+%autoreconf
+%configure \
+ --sysconfdir="%_sysconfdir/burp" \
+ --disable-static
+
+%make_build
+
+%install
+%makeinstall_std install-all
+install -D -p -m 0755 .gear/burp.init %{buildroot}%{_initrddir}/burp-server
+install -D -p -m 0644 .gear/burp.service %{buildroot}%{_unitdir}/burp-server.service
+%__subst "s,password,#password,g" %{buildroot}%_sysconfdir/burp/clientconfdir/testclient
+
+%check
+%make_build check
+.gear/test-burp.sh
+
+%files
+%doc %_docdir/%name/
+%{_initrddir}/burp-server
+%{_unitdir}/burp-*.*
+%dir %_datadir/%name/
+%_datadir/%name/scripts/
+%_bindir/vss_strip
+%_sbindir/*
+%_man8dir/*
+%defattr(640,root,_burp,3770)
+%dir %_sysconfdir/burp/
+%dir %_sysconfdir/burp/CA-client/
+%dir %_sysconfdir/burp/clientconfdir/
+%dir %_sysconfdir/burp/clientconfdir/incexc/
+%config(noreplace) %_sysconfdir/burp/*.c*nf
+%config(noreplace) %_sysconfdir/burp/clientconfdir/testclient
+%config(noreplace) %_sysconfdir/burp/clientconfdir/incexc/example
+
+%pre
+/usr/sbin/groupadd -r -f _burp
+/usr/sbin/useradd -r -g _burp -d /var/empty -s /dev/null -n -c "BURP BackUp and Restore Program" _burp >/dev/null 2>&1 ||:
+
+%post
+%post_service burp-server
+
+%preun
+%preun_service burp-server
+
+%changelog
+* Wed Feb 12 2020 Vitaly Chikunov <vt@altlinux.org> 2.3.16-alt3
+- Remove parasite dependencies from optional scripts.
+
+* Fri Dec 06 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.16-alt2
+- Adjust chkconfig runlevels so that server isn't enabled by default
+- Make _burp:_burp user and configs owned by root:_burp
+- Fix setgid if group= is not specified
+- Add small functionality test
+
+* Mon Nov 25 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.16-alt1
+- New version 2.3.16
+- Fix license string
+- Fix compatibility with openssl-1.1.1
+- Implement support of keeping readall capabilities
+
+* Tue Oct 01 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.14-alt1
+- New version 2.3.14
+
+* Wed Apr 03 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.4-alt1
+- New version 2.3.4
+
+* Fri Mar 15 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.2-alt1
+- new version 2.3.2
+
+* Wed Feb 20 2019 Vitaly Chikunov <vt@altlinux.org> 2.3.0-alt1
+- Update to 2.3.0-12-g3d093f25
+
+* Wed Aug 29 2018 Grigory Ustinov <grenka@altlinux.org> 2.2.4-alt1.1
+- NMU: Rebuild with new openssl 1.1.0.
+
+* Wed Jun 06 2018 Vitaly Chikunov <vt@altlinux.org> 2.2.4-alt1
+- Update to version 2.2.4
+
+* Thu Apr 19 2018 Vitaly Chikunov <vt@altlinux.org> 2.1.32-alt2
+- Fix init script
+- Secure permissions for configs that supposed to contain passwords
+
+* Sun Apr 15 2018 Vitaly Chikunov <vt@altlinux.org> 2.1.32-alt1
+- Respec for 2.1.32
+- Install init scripts
+
+* Tue Dec 05 2017 Vitaly Lipatov <lav@altlinux.ru> 2.1.24-alt1
+- new version 2.1.24 (with rpmrb script)
+
+* Wed Aug 10 2016 Vitaly Lipatov <lav@altlinux.ru> 2.0.44-alt1
+- initial build for ALT Linux Sisyphus
+
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 00000000..e47cc414
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,3 @@
+spec: .gear/burp.spec
+diff: @version@:. .
+tar: @version@:.
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 00000000..2ef2772e
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+6fd6314fecfabb294e6b587fda77934f133e4b22 2.3.16
diff --git a/.gear/test-burp.sh b/.gear/test-burp.sh
new file mode 100755
index 00000000..75c0f418
--- /dev/null
+++ b/.gear/test-burp.sh
@@ -0,0 +1,71 @@
+#!/bin/bash -efu
+
+cd $(dirname $0)
+
+buildroot=$(set +f; echo /usr/src/tmp/*-buildroot)
+home=/usr/src/burp
+PATH=$buildroot/usr/sbin:$PATH
+
+echo "==============="
+echo "FUNCTIONAL TEST"
+echo "==============="
+_err() {
+ ERR=$?
+ echo =======
+ echo FAILURE $ERR
+ echo =======
+ exit $ERR
+}
+trap _err ERR
+
+V() {
+ echo "RUN: $*"
+ "$@"
+}
+
+mkdir -p $home/{client,server,bin}
+mkdir -p $home/client/CA-client
+mkdir -p $home/server/clientconfdir
+mkdir -p $home/server/spool
+
+cp $buildroot/usr/sbin/burp_ca $home/bin/
+cp $buildroot/etc/burp/CA.cnf $home/server/
+
+sed -i "s,^etc=.*,etc=$home/server," $home/bin/burp_ca
+sed -i "s,^CA_DIR.*,CA_DIR = $home/server/CA," $home/server/CA.cnf
+grep ^password test-client.conf > $home/server/clientconfdir/testclient
+
+_kill() {
+ trap - EXIT
+ kill $(cat $home/server/burp.server.pid)
+ wait
+}
+# For debugging of this inside of hasher, othervise hasher-priv
+# could hang on exit from hsh-shell
+trap _kill EXIT
+
+V burp -c test-server.conf -g
+V burp -c test-server.conf -F &
+sleep 1 # Allow them time to startup
+
+V burp -c test-client.conf -al
+V burp -c test-client.conf -ab
+
+# Allow some time for server to settle backup
+for i in $(seq 10); do
+ if [ -e $home/server/spool/testclient/current ]; then
+ echo "Backup settled ($i)"
+ break
+ fi
+ sleep $i
+done
+
+V burp -c test-client.conf -ar -d $home -s3 -f
+_kill
+
+# And now
+V diff -r /usr/src/RPM $home/RPM
+
+echo =======
+echo SUCCESS
+echo =======
diff --git a/.gear/test-client.conf b/.gear/test-client.conf
new file mode 100644
index 00000000..1ddea122
--- /dev/null
+++ b/.gear/test-client.conf
@@ -0,0 +1,23 @@
+mode = client
+server = 127.0.0.1:4971
+status_port = 4972
+password = abcdefgh
+cname = testclient
+pidfile = /usr/src/burp/client/burp.client.pid
+syslog = 0
+stdout = 1
+progress_counter = 0
+server_can_restore = 0
+cross_filesystem = /home
+cross_all_filesystems = 0
+ca_burp_ca = /usr/src/burp/bin/burp_ca
+ca_csr_dir = /usr/src/burp/client/CA-client
+ssl_cert_ca = /usr/src/burp/client/ssl_cert_ca.pem
+ssl_cert = /usr/src/burp/client/ssl_cert-client.pem
+ssl_key = /usr/src/burp/client/ssl_cert-client.key
+ssl_peer_cn = burpserver
+include = /usr/src/RPM
+exclude_fs = sysfs
+nobackup = .nobackup
+exclude_comp = bz2
+exclude_comp = gz
diff --git a/.gear/test-server.conf b/.gear/test-server.conf
new file mode 100644
index 00000000..312b3189
--- /dev/null
+++ b/.gear/test-server.conf
@@ -0,0 +1,33 @@
+mode = server
+listen = 0.0.0.0:4971
+max_children = 5
+directory = /usr/src/burp/server/spool
+dedup_group = global
+clientconfdir = /usr/src/burp/server/clientconfdir
+pidfile = /usr/src/burp/server/burp.server.pid
+hardlinked_archive = 0
+working_dir_recovery_method = delete
+umask = 0022
+syslog = 0
+stdout = 1
+client_can_delete = 1
+client_can_diff = 1
+client_can_force_backup = 1
+client_can_list = 1
+client_can_monitor = 1
+client_can_restore = 1
+client_can_verify = 1
+version_warn = 1
+keep = 7
+ca_conf = /usr/src/burp/server/CA.cnf
+ca_name = burpCA
+ca_server_name = burpserver
+ca_burp_ca = /usr/src/burp/bin/burp_ca
+ca_crl_check = 1
+ssl_cert_ca = /usr/src/burp/server/ssl_cert_ca.pem
+ssl_cert = /usr/src/burp/server/ssl_cert-server.pem
+ssl_key = /usr/src/burp/server/ssl_cert-server.key
+ssl_dhfile = /usr/src/burp/server/dhfile.pem
+timer_arg = 20h
+timer_arg = Mon,Tue,Wed,Thu,Fri,00,01,02,03,04,05,19,20,21,22,23
+timer_arg = Sat,Sun,00,01,02,03,04,05,06,07,08,17,18,19,20,21,22,23
diff --git a/.gear/upstream/remotes b/.gear/upstream/remotes
new file mode 100644
index 00000000..cd34b75c
--- /dev/null
+++ b/.gear/upstream/remotes
@@ -0,0 +1,3 @@
+[remote "upstream"]
+ url = git://github.com/grke/burp.git
+ fetch = +refs/heads/*:refs/remotes/upstream/*
diff --git a/Makefile.am b/Makefile.am
index cfb1cc14..050523ca 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -118,7 +118,8 @@ main_LDADD = \
$(NCURSES_LIBS) \
$(OPENSSL_LIBS) \
$(RSYNC_LIBS) \
- $(ZLIBS)
+ $(ZLIBS) \
+ $(CAP_LIBS)
main_CPPFLAGS = \
$(AM_CPPFLAGS) \
@@ -399,7 +400,8 @@ runner_LDADD = \
$(NCURSES_LIBS) \
$(RSYNC_LIBS) \
$(OPENSSL_LIBS) \
- $(ZLIBS)
+ $(ZLIBS) \
+ $(CAP_LIBS)
coverage: check
if WITH_COVERAGE
diff --git a/android/burp_ca b/android/burp_ca
index 026ad468..e57cf43e 100755
--- a/android/burp_ca
+++ b/android/burp_ca
@@ -9,7 +9,6 @@ name="$8"
echo "generating key ${name}: ${keypath}"
${burp_dir}/openssl genrsa -out "${keypath}" 2048
-echo 'RANDFILE = /dev/urandom' > "${tmpconf}"
echo '[ req ]' >> "${tmpconf}"
echo 'distinguished_name = req_distinguished_name' >> "${tmpconf}"
echo 'prompt = no' >> "${tmpconf}"
diff --git a/configs/certs/CA/CA.cnf.in b/configs/certs/CA/CA.cnf.in
index 35b85686..073378fe 100644
--- a/configs/certs/CA/CA.cnf.in
+++ b/configs/certs/CA/CA.cnf.in
@@ -1,6 +1,5 @@
# simple config for burp_ca
-RANDFILE = /dev/urandom
CA_DIR = @sysconfdir@/CA
diff --git a/configs/certs/CA/burp_ca.bat.in b/configs/certs/CA/burp_ca.bat.in
index 960e108c..2f75955f 100644
--- a/configs/certs/CA/burp_ca.bat.in
+++ b/configs/certs/CA/burp_ca.bat.in
@@ -40,7 +40,6 @@ echo "generating key %name%: %keypath%"
REM Need to create a config file for openssl in order to make a certicate
REM signing request. There must be a neater way to do it than one line at a time
REM and %tmpconf% at the end each time.
-echo RANDFILE = /dev/urandom > "%tmpconf%"
echo [ req ] >> "%tmpconf%"
echo distinguished_name = req_distinguished_name >> "%tmpconf%"
echo prompt = no >> "%tmpconf%"
diff --git a/configs/certs/CA/burp_ca.in b/configs/certs/CA/burp_ca.in
index 3a3c054c..ad4a5b62 100755
--- a/configs/certs/CA/burp_ca.in
+++ b/configs/certs/CA/burp_ca.in
@@ -190,8 +190,6 @@ if [ "$init" = "yes" ]; then
umask "$def_umask"
TEMP="$(mktemp "/tmp/@name@_ca.tmp.XXXXXXXX" || echo "/tmp/@name@_ca.tmp.$$")"
cat <<-EOF > "$TEMP"
- RANDFILE = /dev/urandom
-
[ req ]
distinguished_name = req_distinguished_name
prompt = no
@@ -237,7 +235,6 @@ if [ "$request" = "yes" ]; then
[ -d "$(dirname "$requestpath")" ] || mkdir "$(dirname "$requestpath")"
TEMP="$(mktemp "/tmp/@name@_ca.tmp.XXXXXXXX" || echo "/tmp/@name@_ca.tmp.$$")"
cat <<-EOF > "$TEMP"
- RANDFILE = /dev/urandom
req_extensions = v3_req
[ req ]
diff --git a/configs/client/burp.conf.in b/configs/client/burp.conf.in
index e9472df4..2a5c22a2 100644
--- a/configs/client/burp.conf.in
+++ b/configs/client/burp.conf.in
@@ -52,8 +52,13 @@ server_can_restore = 0
# . path/to/more/conf
# Run as different user/group.
-# user=graham
-# group=nogroup
+# user=_burp
+# group=_burp
+# Set to 1 to keep 'readall' capability (linux only) when dropping privileges
+# (default is 0, do not keep capability). Readall capability allows process
+# to read all files (even not owned by user) without requiring root privileges.
+# When using readall=1 if user= is not set it's assumed nobody.
+# readall=1
cross_filesystem=/home
cross_all_filesystems=0
diff --git a/configure.ac b/configure.ac
index 9af8921b..517edfbc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -278,6 +278,19 @@ AC_CHECK_HEADERS([librsync.h],
AC_SUBST([RSYNC_LIBS])
+dnl -----------------------------------------------------------
+dnl Check for headers, functions and libraries required to
+dnl support keeping readall capabilities
+dnl -----------------------------------------------------------
+
+AC_CHECK_HEADERS(sys/prctl.h sys/capability.h)
+AC_CHECK_FUNCS(prctl setreuid)
+AC_CHECK_LIB([cap], [cap_set_proc], [CAP_LIBS="-lcap"], [CAP_LIBS=])
+if test x$CAP_LIBS = x-lcap; then
+ have_readall=yes
+ AC_DEFINE(HAVE_LIBCAP, 1, [Define if you have libcap])
+fi
+AC_SUBST([CAP_LIBS])
dnl --------------------------------------------------------------------------
dnl Check whether librsync has RS_BLAKE2_SIG_MAGIC
@@ -536,6 +549,7 @@ AC_MSG_NOTICE([ acl: ${have_acl}])
AC_MSG_NOTICE([ crypt: ${have_crypt}])
AC_MSG_NOTICE([ ipv6: ${enable_ipv6}])
AC_MSG_NOTICE([ ncurses: ${have_ncurses}])
+AC_MSG_NOTICE([ readall: ${have_readall}])
AC_MSG_NOTICE([ openssl: ${have_ssl}])
AC_MSG_NOTICE([ xattr: ${have_xattr}])
AC_MSG_NOTICE([ zlib: ${ac_cv_header_zlib_h}])
diff --git a/manpages/burp.8.in b/manpages/burp.8.in
index ff216e8b..7c1c7664 100644
--- a/manpages/burp.8.in
+++ b/manpages/burp.8.in
@@ -321,6 +321,9 @@ Run as a particular user. This can be overridden by the client configuration fil
\fBgroup=[groupname]\fR
Run as a particular group. This can be overridden by the client configuration files in clientconfdir on the server.
.TP
+\fBreadall=[0|1]\fR
+Keep readall capability when dropping root privileges (default 0). When enabled changes default atime to 1.
+.TP
\fBumask=[umask]\fR
Set the file creation umask. Default is 0022.
.TP
diff --git a/src/conf.c b/src/conf.c
index 64390e7e..f44bddd7 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -572,6 +572,8 @@ static int reset_conf(struct conf **c, enum conf_opt o)
return sc_cntr(c[o], 0, 0, "");
case OPT_VSS_RESTORE:
return sc_int(c[o], VSS_RESTORE_ON, 0, "");
+ case OPT_READALL:
+ return sc_int(c[o], 0, CONF_FLAG_CC_OVERRIDE, "readall");
case OPT_BREAKPOINT:
return sc_int(c[o], 0,
CONF_FLAG_CC_OVERRIDE, "breakpoint");
diff --git a/src/conf.h b/src/conf.h
index bb9e5196..f4bfd11e 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -314,6 +314,9 @@ enum conf_opt
// For testing.
OPT_BREAKPOINT,
+ // readall capability
+ OPT_READALL,
+
OPT_MAX
};
diff --git a/src/handy.c b/src/handy.c
index 1db149c5..88cf50a6 100644
--- a/src/handy.c
+++ b/src/handy.c
@@ -336,7 +336,7 @@ void setup_signal(int sig, void handler(int sig))
}
/* Function based on src/lib/priv.c from bacula. */
-int chuser_and_or_chgrp(const char *user, const char *group)
+int chuser_and_or_chgrp(const char *user, const char *group, int readall)
{
#ifndef HAVE_WIN32
struct passwd *passw = NULL;
@@ -345,6 +345,9 @@ int chuser_and_or_chgrp(const char *user, const char *group)
uid_t uid;
char *username=NULL;
+ // Allow setting readall=1 without setting user
+ if(readall && !user)
+ user="nobody";
if(!user && !group) return 0;
if(user)
@@ -377,41 +380,81 @@ int chuser_and_or_chgrp(const char *user, const char *group)
{
logp("could not find group '%s': %s\n", group,
strerror(errno));
- free_w(&username);
- return -1;
+ goto err;
}
gid=grp->gr_gid;
+ } else {
+ // Resolve git to group name for logp()
+ if (!(grp=getgrgid(gid)))
+ {
+ logp("could not find group for gid %d: %s\n", gid,
+ strerror(errno));
+ goto err;
+ }
+ group=grp->gr_name;
+ grp=NULL;
}
if(gid!=getgid() // do not do it if we already have the same gid.
&& initgroups(username, gid))
{
if(grp)
- logp("could not initgroups for group '%s', user '%s': %s\n", group, user, strerror(errno));
+ logp("could not initgroups for group '%s', user '%s': %s\n", group, username, strerror(errno));
else
- logp("could not initgroups for user '%s': %s\n", user, strerror(errno));
- free_w(&username);
- return -1;
+ logp("could not initgroups for user '%s': %s\n", username, strerror(errno));
+ goto err;
}
- free_w(&username);
- if(grp)
+ if(gid!=getgid() // do not do it if we already have the same gid
+ && setgid(gid))
{
- if(gid!=getgid() // do not do it if we already have the same gid
- && setgid(gid))
+ logp("could not set group '%s': %s\n", group,
+ strerror(errno));
+ goto err;
+ }
+ if (readall)
+ {
+#ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT
+ cap_t caps;
+ // Make capabilities pass through setreuid
+ if(prctl(PR_SET_KEEPCAPS, 1))
{
- logp("could not set group '%s': %s\n", group,
- strerror(errno));
- return -1;
+ logp("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
+ goto err;
}
- }
- if(uid!=getuid() // do not do it if we already have the same uid
+ if(setreuid(uid, uid))
+ {
+ logp("Could not switch to user=%s (uid=%u): %s\n", username, uid, strerror(errno));
+ goto err;
+ }
+ // `ep' is Effective and Permitted
+ caps=cap_from_text("cap_dac_read_search=ep");
+ if(!caps)
+ {
+ logp("cap_from_text() failed: %s\n", strerror(errno));
+ goto err;
+ }
+ if(cap_set_proc(caps) < 0)
+ {
+ logp("cap_set_proc() failed: %s\n", strerror(errno));
+ goto err;
+ }
+ cap_free(caps);
+ logp("Privileges switched to %s keeping readall capability.\n", username);
+#else
+ logp("Keep readall capabilities is not implemented on this platform yet\n");
+ goto err;
+#endif
+ } else if(uid!=getuid() // do not do it if we already have the same uid
&& setuid(uid))
{
logp("could not set specified user '%s': %s\n", username,
strerror(errno));
- return -1;
+ goto err;
}
#endif
return 0;
+err:
+ free_w(&username);
+ return -1;
}
// Not in dpth.c so that Windows client can see it.
diff --git a/src/handy.h b/src/handy.h
index 2f2f9401..cdf92c3a 100644
--- a/src/handy.h
+++ b/src/handy.h
@@ -9,6 +9,16 @@
#include "bfile.h"
+#undef ENABLE_KEEP_READALL_CAPS_SUPPORT
+#if defined(HAVE_SYS_PRCTL_H) && defined(HAVE_SYS_CAPABILITY_H) && \
+ defined(HAVE_PRCTL) && defined(HAVE_SETREUID) && defined(HAVE_LIBCAP)
+# include <sys/prctl.h>
+# include <sys/capability.h>
+# if defined(PR_SET_KEEPCAPS)
+# define ENABLE_KEEP_READALL_CAPS_SUPPORT
+# endif
+#endif
+
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
@@ -23,7 +33,7 @@ extern int set_peer_env_vars(struct sockaddr_storage *addr);
extern int set_keepalive(int fd, int value);
extern int init_client_socket(const char *host, const char *port);
extern void reuseaddr(int fd);
-extern int chuser_and_or_chgrp(const char *user, const char *group);
+extern int chuser_and_or_chgrp(const char *user, const char *group, int readall);
extern int dpth_protocol1_is_compressed(int compressed, const char *datapath);
#ifndef HAVE_WIN32
extern void setup_signal(int sig, void handler(int sig));
diff --git a/src/prog.c b/src/prog.c
index 16a9e653..218641d4 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -308,6 +308,7 @@ int real_main(int argc, char *argv[])
int test_confs=0;
enum burp_mode mode;
struct strlist *cli_overrides=NULL;
+ int keep_readall_caps=0;
log_init(argv[0]);
#ifndef HAVE_WIN32
@@ -498,6 +499,12 @@ int real_main(int argc, char *argv[])
case ACTION_BACKUP:
case ACTION_BACKUP_TIMED:
case ACTION_TIMER_CHECK:
+#ifdef ENABLE_KEEP_READALL_CAPS_SUPPORT
+ keep_readall_caps=get_int(confs[OPT_READALL]);
+ // readall=1 cannot work with atime=0 (O_NOATIME)
+ if (keep_readall_caps)
+ set_int(confs[OPT_ATIME], 1);
+#endif
// Need to get the lock.
if(!(lock=get_prog_lock(confs)))
goto end;
@@ -509,7 +516,8 @@ int real_main(int argc, char *argv[])
// Change privileges after having got the lock, for convenience.
if(chuser_and_or_chgrp(
- get_string(confs[OPT_USER]), get_string(confs[OPT_GROUP])))
+ get_string(confs[OPT_USER]), get_string(confs[OPT_GROUP]),
+ keep_readall_caps))
return -1;
set_int(confs[OPT_OVERWRITE], forceoverwrite);
diff --git a/src/server/child.c b/src/server/child.c
index 27f2c665..c0977f86 100644
--- a/src/server/child.c
+++ b/src/server/child.c
@@ -194,7 +194,7 @@ int child(struct async *as, int is_status_server,
if( (!confs_user || (cconfs_user && strcmp(confs_user, cconfs_user)))
||(!confs_group ||(cconfs_group && strcmp(confs_group,cconfs_group))))
{
- if(chuser_and_or_chgrp(cconfs_user, cconfs_group))
+ if(chuser_and_or_chgrp(cconfs_user, cconfs_group, 0))
{
log_and_send(as->asfd,
"chuser_and_or_chgrp failed on server");
diff --git a/utest/test_conf.c b/utest/test_conf.c
index eb0574fc..04f5e9d1 100644
--- a/utest/test_conf.c
+++ b/utest/test_conf.c
@@ -82,6 +82,7 @@ static void check_default(struct conf **c, enum conf_opt o)
case OPT_B_SCRIPT_POST_RUN_ON_FAIL:
case OPT_R_SCRIPT_POST_RUN_ON_FAIL:
case OPT_SEND_CLIENT_CNTR:
+ case OPT_READALL:
case OPT_BREAKPOINT:
case OPT_SYSLOG:
case OPT_PROGRESS_COUNTER: