From 202e2edd5acdd547a2610fef3e992ccd3266025a Mon Sep 17 00:00:00 2001 From: Florian Schlichting Date: Tue, 9 Feb 2021 01:23:54 +0800 Subject: [PATCH] tighten $c->list_everyone to look for DAV::read privilege and actually block access to principals and collections Groups really only exist in the davical web interface, CALDAV clients discover principals and collections based on GRANTs such as the DAV::read privilege, so use that for the web interface as well. Also, not listing users is nice, actually blocking access to those users (which can be enumerated with the id GET parameter) is a lot better. --- config/example-config.php | 7 +++++-- inc/ui/collection-edit.php | 8 ++++++++ inc/ui/principal-browse.php | 11 ++--------- inc/ui/principal-edit.php | 8 ++++++++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/config/example-config.php b/config/example-config.php index 8827e6b0..7be5509e 100644 --- a/config/example-config.php +++ b/config/example-config.php @@ -114,8 +114,11 @@ $c->admin_email ='calendar-admin@example.com'; // $c->print_styles = array(); /** -* Allow users to see all accounts listed, or only their account and -* the accounts they have a relationship to in the web interface. +* Allow users to see all accounts on the server in the web interface, or only +* their account and the accounts they have a relationship with. If set to +* false, users need the READ privilege to display another principal and their +* collections, and they need to be in the same group with another principal to +* find them in a drop-down list for granting privileges. * Admins will still be able to see all accounts. * Default: true */ diff --git a/inc/ui/collection-edit.php b/inc/ui/collection-edit.php index 1096839a..1211e7a5 100644 --- a/inc/ui/collection-edit.php +++ b/inc/ui/collection-edit.php @@ -64,6 +64,14 @@ if ( isset($privsql) ) { $privqry->Exec('admin-collection-edit',__LINE__,__FILE__); $permissions = $privqry->Fetch(); $can_write_collection = ($session->AllowedTo('Admin') || (bindec($permissions->priv) & privilege_to_bits('DAV::bind')) ); + if ( ! $c->list_everyone ) { + $can_read_collection = ($session->AllowedTo('Admin') || (bindec($permissions->priv) & privilege_to_bits('DAV::read')) ); + if ( ! $can_read_collection ) { + dbg_error_log( 'LOG WARNING', 'Access to id "%s"/"%s" by user "%s" rejected.', $id, $collection_name, $session->username ); + header('Location: index.php'); + @ob_flush(); exit(0); + } + } } // Verify CSRF token diff --git a/inc/ui/principal-browse.php b/inc/ui/principal-browse.php index 4aa251e3..b59c1a4a 100644 --- a/inc/ui/principal-browse.php +++ b/inc/ui/principal-browse.php @@ -35,15 +35,8 @@ if ( isset($principal_type) ) { $browser->AndWhere( 'type_id = '.$principal_type ); } -if ( ! $c->list_everyone ) { - if ( ! $session->AllowedTo( "Admin" ) ) { - if ( isset($principal_type) && ( $principal_type == 1 || $principal_type == 2 ) ) { - $browser->AndWhere( '(principal_id = \''.$session->principal_id.'\' or principal_id in (select member_id from group_member where group_id in (select group_id from group_member where member_id = \''.$session->principal_id.'\')))' ); - } - if ( isset($principal_type) && $principal_type == 3 ) { - $browser->AndWhere( '(principal_id = \''.$session->principal_id.'\' or principal_id in (select group_id from group_member where member_id = \''.$session->principal_id.'\'))' ); - } - } +if ( ! $c->list_everyone && ! $session->AllowedTo( "Admin" ) ) { + $browser->AndWhere( '(pprivs('.$session->principal_id.',dav_principal.principal_id,'.$c->permission_scan_depth.') & 1::BIT(24))::INT4::BOOLEAN' ); } $c->page_title = $browser->Title(); diff --git a/inc/ui/principal-edit.php b/inc/ui/principal-edit.php index b6983d79..a6de8305 100644 --- a/inc/ui/principal-edit.php +++ b/inc/ui/principal-edit.php @@ -33,6 +33,14 @@ $can_write_principal = ($session->AllowedTo('Admin') || ($session->principal_id if ( !$can_write_principal && $id > 0 ) { $target_principal = new Principal('principal_id', $id); $can_write_principal = $session->HavePrivilegeTo('DAV::write', $target_principal->dav_name()); + if ( ! $c->list_everyone ) { + $can_read_principal = $session->HavePrivilegeTo('DAV::read', $target_principal->dav_name()); + if ( ! $can_read_principal ) { + dbg_error_log( 'LOG WARNING', 'Access to "%s" by user "%s" rejected.', $target_principal->dav_name(), $session->username ); + header('Location: index.php'); + @ob_flush(); exit(0); + } + } }