From f533a44f3f5ce636e328e44c45a2673595e9e1ad Mon Sep 17 00:00:00 2001
From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Date: Wed, 31 Jan 2018 15:02:36 +0100
Subject: [PATCH] Bug 20100: Disallow access to superlib privileges at server
 side
Content-Type: text/plain; charset=utf-8

Depends on pref ProtectSuperlibPrivs.
If enabled, script member-flags.pl will not allow you to add or remove
superlib privs when you are no superlibrarian.
The follow-up patch will enable the check at client side.

Test plan:
[1] Enable the pref. Do not apply the third patch (client side).
[2] Login as superlib and add/remove superlib privs to a staff user.
[3] Login as another user (no superlib, but having borrowers, permissions
    and staff_access). Verify that you have an internal server error when
    you add or remove superlib privs. The log contains a warning.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
---
 members/member-flags.pl | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/members/member-flags.pl b/members/member-flags.pl
index 2398189..f5734d5 100755
--- a/members/member-flags.pl
+++ b/members/member-flags.pl
@@ -87,7 +87,17 @@ if ($input->param('newflags')) {
     }
     
     $sth = $dbh->prepare("UPDATE borrowers SET flags=? WHERE borrowernumber=?");
-    $sth->execute($module_flags, $member);
+    if( !C4::Context->preference('ProtectSuperlibPrivs') || C4::Context->IsSuperLibrarian ) {
+        $sth->execute($module_flags, $member);
+    } else {
+        my $old_flags = $patron->flags // 0;
+        if( ( $old_flags == 1 || $module_flags == 1 ) &&
+              $old_flags != $module_flags ) {
+           die "Non-superlibrarian is changing superlibrarian privileges"; # Interface should not allow this, so we can just die here
+        } else {
+            $sth->execute($module_flags, $member);
+        }
+    }
     
     # deal with subpermissions
     $sth = $dbh->prepare("DELETE FROM user_permissions WHERE borrowernumber = ?");
@@ -200,6 +210,7 @@ $template->param(
     loop           => \@loop,
     csrf_token =>
         Koha::Token->new->generate_csrf( { session_id => scalar $input->cookie('CGISESSID'), } ),
+    disable_superlibrarian_privs => C4::Context->preference('ProtectSuperlibPrivs') ? !C4::Context->IsSuperLibrarian : 0,
 );
 
     output_html_with_http_headers $input, $cookie, $template->output;
-- 
2.1.4