From 152ce12fc37d3e6a8a568d04a199541422872fa4 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sun, 14 Dec 2014 11:33:33 -0800 Subject: [PATCH] Use folder permissions for opendir --- mailboxes/boxes-lib.pl | 62 ++++++++++++++++++++++++++-------------- mailboxes/folders-lib.pl | 34 ++++++++++++---------- 2 files changed, 59 insertions(+), 37 deletions(-) diff --git a/mailboxes/boxes-lib.pl b/mailboxes/boxes-lib.pl index 93098c4f5..a31e8a29d 100755 --- a/mailboxes/boxes-lib.pl +++ b/mailboxes/boxes-lib.pl @@ -1961,7 +1961,7 @@ else { # Really read local @shorts; foreach my $d ("cur", "new") { - opendir(DIR, "$_[0]/$d"); + &opendir_as_mail_user(DIR, "$_[0]/$d") || &error("Failed to open $_[0]/$d : $!"); while(my $f = readdir(DIR)) { next if ($f eq "." || $f eq ".."); if ($skipt && $f =~ /:2,([A-Za-z]*T[A-Za-z]*)$/) { @@ -2193,7 +2193,7 @@ sub empty_maildir local $d; foreach $d ("$_[0]/cur", "$_[0]/new") { local $f; - opendir(DIR, $d); + &opendir_as_mail_user(DIR, $d) || &error("Failed to open $d : $!"); while($f = readdir(DIR)) { unlink("$d/$f") if ($f ne '.' && $f ne '..'); } @@ -2240,7 +2240,7 @@ return scalar(@files); sub list_mhdir { local ($start, $end, $f, $i, @rv); -opendir(DIR, $_[0]); +&opendir_as_mail_user(DIR, $_[0]) || &error("Failed to open $_[0] : $!"); local @files = map { "$_[0]/$_" } sort { $a <=> $b } grep { /^\d+$/ } readdir(DIR); @@ -2280,7 +2280,7 @@ return @rv; sub idlist_mhdir { local ($dir) = @_; -opendir(DIR, $dir); +&opendir_as_mail_user(DIR, $dir) || &error("Failed to open $dir : $!"); local @files = grep { /^\d+$/ } readdir(DIR); closedir(DIR); return @files; @@ -2300,7 +2300,7 @@ sub select_mhdir { local ($file, $ids, $headersonly) = @_; local @rv; -opendir(DIR, $file); +&opendir_as_mail_user(DIR, $file) || &error("Failed to open $file : $!"); local @files = map { "$file/$_" } sort { $a <=> $b } grep { /^\d+$/ } readdir(DIR); @@ -2363,8 +2363,8 @@ unlink($_[0]->{'file'}); sub max_mhdir { local $max = 1; -opendir(DIR, $_[0]); -foreach $f (readdir(DIR)) { +&opendir_as_mail_user(DIR, $_[0]) || &error("Failed to open $_[0] : $!"); +foreach my $f (readdir(DIR)) { $max = $f if ($f =~ /^\d+$/ && $f > $max); } closedir(DIR); @@ -2375,9 +2375,8 @@ return $max; # Delete all messages in an MH format directory sub empty_mhdir { -local $f; -opendir(DIR, $_[0]); -foreach $f (readdir(DIR)) { +&opendir_as_mail_user(DIR, $_[0]) || &error("Failed to open $_[0] : $!"); +foreach my $f (readdir(DIR)) { unlink("$_[0]/$f") if ($f =~ /^\d+$/); } closedir(DIR); @@ -2387,7 +2386,7 @@ closedir(DIR); # Returns the number of messages in an MH directory sub count_mhdir { -opendir(DIR, $_[0]); +&opendir_as_mail_user(DIR, $_[0]) || &error("Failed to open $_[0] : $!"); local @files = grep { /^\d+$/ } readdir(DIR); closedir(DIR); return scalar(@files); @@ -2827,8 +2826,34 @@ $main::mail_open_user = undef; sub open_as_mail_user { my ($fh, $file) = @_; -my $switched = 0; -print STDERR "file=$file user=$main::mail_open_user <=$< >=$>\n"; +my $switched = &switch_to_mail_user(); +my $rv = open($fh, $file); +if ($switched) { + # Now that it is open, switch back to root + $) = 0; + $> = 0; + } +return $rv; +} + +# opendir_as_mail_user(fh, dir) +# Calls the opendir function, but as the user set by set_mail_open_user +sub opendir_as_mail_user +{ +my ($fh, $dir) = @_; +my $switched = &switch_to_mail_user(); +my $rv = opendir($fh, $dir); +if ($switched) { + $) = 0; + $> = 0; + } +return $rv; +} + +# switch_to_mail_user() +# Sets the permissions used for reading files +sub switch_to_mail_user +{ if (defined($main::mail_open_user) && !$< && !$>) { # Switch file permissions to the correct user my @uinfo = $main::mail_open_user =~ /^\d+$/ ? @@ -2838,16 +2863,9 @@ if (defined($main::mail_open_user) && !$< && !$>) { "does not exists"); $) = $uinfo[3]." ".join(" ", $uinfo[3], &other_groups($uinfo[0])); $> = $uinfo[2]; - $switched = 1; + return 1; } -my $rv = open($fh, $file); -if ($switched) { - # Now that it is open, switch back to root - $) = 0; - $> = 0; - } -print STDERR "rv=$rv err=$!\n"; -return $rv; +return 0; } 1; diff --git a/mailboxes/folders-lib.pl b/mailboxes/folders-lib.pl index 0a430f2b9..70667c04a 100755 --- a/mailboxes/folders-lib.pl +++ b/mailboxes/folders-lib.pl @@ -576,16 +576,17 @@ return $mail; sub mailbox_idlist { local ($folder) = @_; +&switch_to_folder_user($_[0]); +my @idlist; if ($folder->{'type'} == 0) { # mbox, for which IDs are mail positions print DEBUG "starting to get IDs from $folder->{'file'}\n"; - local @idlist = &idlist_mails($folder->{'file'}); + @idlist = &idlist_mails($folder->{'file'}); print DEBUG "got ",scalar(@idlist)," ids\n"; - return @idlist; } elsif ($folder->{'type'} == 1) { # maildir, for which IDs are filenames - return &idlist_maildir($folder->{'file'}); + @idlist = &idlist_maildir($folder->{'file'}); } elsif ($folder->{'type'} == 2) { # pop3, for which IDs are uidls @@ -596,12 +597,11 @@ elsif ($folder->{'type'} == 2) { else { &error(&text('save_elogin', $rv[1])); } } local $h = $rv[1]; - local @uidl = &pop3_uidl($h); - return @uidl; + @idlist = &pop3_uidl($h); } elsif ($folder->{'type'} == 3) { # MH directory, for which IDs are file numbers - return &idlist_mhdir($folder->{'file'}); + @idlist = &idlist_mhdir($folder->{'file'}); } elsif ($folder->{'type'} == 4) { # IMAP, for which IDs are IMAP UIDs @@ -618,22 +618,18 @@ elsif ($folder->{'type'} == 4) { $folder->{'lastchange'} = $irv[3] if ($irv[3]); @rv = &imap_command($h, "FETCH 1:$count UID"); - local @uids; foreach my $uid (@{$rv[1]}) { if ($uid =~ /UID\s+(\d+)/) { - push(@uids, $1); + push(@idlist, $1); } } - return @uids; } elsif ($folder->{'type'} == 5) { # Composite, IDs come from sub-folders - local @rv; foreach my $sf (@{$folder->{'subfolders'}}) { local $sfn = &folder_name($sf); - push(@rv, map { $sfn."\t".$_ } &mailbox_idlist($sf)); + push(@idlist, map { $sfn."\t".$_ } &mailbox_idlist($sf)); } - return @rv; } elsif ($folder->{'type'} == 6) { # Virtual, IDs come from sub-folders (where they exist) @@ -645,18 +641,18 @@ elsif ($folder->{'type'} == 6) { push(@{$wantmap{$sfn}}, $sid); $namemap{$sfn} = $sf; } - local @rv; foreach my $sfn (keys %wantmap) { local %wantids = map { $_, 1 } @{$wantmap{$sfn}}; local $sf = $namemap{$sfn}; foreach my $sfid (&mailbox_idlist($sf)) { if ($wantids{$sfid}) { - push(@rv, $sfn."\t".$sfid); + push(@idlist, $sfn."\t".$sfid); } } } - return @rv; } +&switch_from_folder_user($_[0]); +return @idlist; } # compute_start_end(start, end, count) @@ -927,6 +923,7 @@ return &user_index_file(($folder->{'file'} || $folder->{'id'}).".byid"); sub mailbox_search_mail { local ($fields, $andmode, $folder, $limit, $headersonly) = @_; +# XXX user permissions fix needed # For folders other than IMAP and composite and mbox where we already have # an index, build a sort index and use that for @@ -1123,6 +1120,7 @@ elsif ($folder->{'type'} == 6) { # Delete multiple messages from some folder sub mailbox_delete_mail { +# XXX user permissions fix needed return undef if (&is_readonly_mode()); local $f = shift(@_); if ($userconfig{'delete_mode'} == 1 && !$f->{'trash'} && !$f->{'spam'} && @@ -1300,6 +1298,7 @@ if ($folder->{'sortable'}) { sub mailbox_copy_folder { local ($src, $dest) = @_; +# XXX user permissions fix needed if ($src->{'type'} == 0 && $dest->{'type'} == 0) { # mbox to mbox .. just read and write the files &open_readfile(SOURCE, $src->{'file'}); @@ -1352,6 +1351,7 @@ else { sub mailbox_move_mail { return undef if (&is_readonly_mode()); +# XXX user permissions fix needed local $src = shift(@_); local $dst = shift(@_); local $now = time(); @@ -1423,6 +1423,7 @@ return 0; # Moves all mail from one folder to another, possibly converting the type sub mailbox_move_folder { +# XXX user permissions fix needed return undef if (&is_readonly_mode()); local ($src, $dst) = @_; if ($src->{'type'} == $dst->{'type'} && !$src->{'remote'}) { @@ -1474,6 +1475,7 @@ if ($src->{'sortable'}) { # Copy mail from one folder to another sub mailbox_copy_mail { +# XXX user permissions fix needed return undef if (&is_readonly_mode()); local $src = shift(@_); local $dst = shift(@_); @@ -1550,6 +1552,7 @@ if ($_[0]->{'type'} == 1) { # Writes some mail message to a folder sub write_mail_folder { +# XXX user permissions fix needed return undef if (&is_readonly_mode()); &create_folder_maildir($_[1]); local $needid; @@ -1618,6 +1621,7 @@ if ($needid) { sub mailbox_modify_mail { local ($oldmail, $mail, $folder, $textonly) = @_; +# XXX user permissions fix needed return undef if (&is_readonly_mode()); if ($folder->{'type'} == 1) {