diff --git a/pg_ctlcluster b/pg_ctlcluster index b4c6410deafa83a40e2ddd58599777d8ee8bc40a..ecb7c92fa512260d9a72ddc31f1cef33d1fbc6e5 100755 --- a/pg_ctlcluster +++ b/pg_ctlcluster @@ -420,13 +420,9 @@ if (not $skip_systemctl_redirect and getppid() != 1 and # not run from init error "cluster is running from systemd, can only restart it as root. Try instead:\n sudo systemctl $action postgresql\@$version-$cluster"; # program end # otherwise just raise a warning on start and restart as non-root - } elsif (-t 1) { - if ($action =~ /start/) { - print "Warning: the cluster will not be running as a systemd service. Consider using systemctl:\n"; - } elsif ($unit_active) { # on stop, warn when running from systemd - print "Warning: stopping the cluster using pg_ctlcluster will mark the systemd unit as failed. Consider using systemctl:\n"; - } - print " sudo systemctl $action postgresql\@$version-$cluster\n"; + } else { + print "Redirecting $1 request to sudo\n" if (-t 1); + system ('sudo', '/usr/share/postgresql-common/pg_ctlcluster.sudo', $version, $cluster, $action); } } diff --git a/systemd/Makefile b/systemd/Makefile index ace0c2d1417303803a72d88f344aaca5bd31154f..94c0d485ebbdfe96cd22eaf9866a0adbdead1f82 100644 --- a/systemd/Makefile +++ b/systemd/Makefile @@ -2,6 +2,11 @@ install: install -d $(DESTDIR)/lib/systemd/system-generators/ $(DESTDIR)/lib/systemd/system/ install postgresql-generator $(DESTDIR)/lib/systemd/system-generators/ install -m644 postgresql*.service $(DESTDIR)/lib/systemd/system/ + + install -d $(DESTDIR)/usr/share/postgresql-common/ + install pg_ctlcluster.sudo $(DESTDIR)/usr/share/postgresql-common/ + install -d $(DESTDIR)/etc/sudoers.d/ + install -m400 postgresql-common.sudoers $(DESTDIR)/etc/sudoers.d/postgresql-common reload: install systemctl daemon-reload diff --git a/systemd/pg_ctlcluster.sudo b/systemd/pg_ctlcluster.sudo new file mode 100755 index 0000000000000000000000000000000000000000..43762a74284259aefc6bd26a149c82047d92210f --- /dev/null +++ b/systemd/pg_ctlcluster.sudo @@ -0,0 +1,48 @@ +#!/usr/bin/perl -wT + +# pg_ctlcluster to sudo-systemctl wrapper +# +# (C) 2015 Christoph Berg <myon@debian.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +use strict; +use warnings; +use PgCommon; + +# sudo sanity checking +exists ($ENV{SUDO_UID}) or error "SUDO_UID is unset, pg_ctlcluster.sudo must be invoked through sudo"; +my ($sudo_uid) = $ENV{SUDO_UID} =~ /^(\d+)$/; + +# wipe environment +%ENV = ( + PATH => '/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin', +); + +# argument handling +@ARGV == 3 or error "pg_ctlcluster.sudo must be invoked with exactly 3 arguments"; +my ($version) = $ARGV[0] =~ /^(\d+\.\d+)$/ or error "malformatted version number"; +my ($cluster) = $ARGV[1] =~ /^([^'"\s]+)$/ or error "malformatted cluster name"; +my ($action) = $ARGV[2] =~ /^(start|stop|restart|reload)$/ or error "malformatted action"; +cluster_exists ($version, $cluster) or error "specified cluster does not exist"; + +# cluster owner checking +my %info = cluster_info ($version, $cluster); +exists ($info{owneruid}) or error "could not determine cluster owner UID"; +exists ($info{configuid}) or error "could not determine cluster config UID"; +$info{owneruid} == $sudo_uid or error "user does not own cluster data directory"; +if ($info{configuid} != 0) { + $info{configuid} == $sudo_uid or error "user does not own cluster config"; +} + +# forward action to systemctl +system "/bin/systemctl", $action, "postgresql\@$version-$cluster"; +exit $? >> 8; diff --git a/systemd/postgresql-common.sudoers b/systemd/postgresql-common.sudoers new file mode 100644 index 0000000000000000000000000000000000000000..b3cbe6f9aaa1ef75c73618eea2838489ca11137d --- /dev/null +++ b/systemd/postgresql-common.sudoers @@ -0,0 +1,2 @@ +# Allow postgres to manage database clusters +postgres ALL=(root) NOPASSWD: /usr/share/postgresql-common/pg_ctlcluster.sudo