From c031dfcb18eb8b2608aa5e9498cfdbbdb99c87e0 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sat, 27 Dec 2014 20:26:48 -0800 Subject: [PATCH] Allow nested calls to switch function, check perms when copying a folder --- mailboxes/boxes-lib.pl | 28 ++++++++++++++++++++++++++- mailboxes/folders-lib.pl | 41 +++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/mailboxes/boxes-lib.pl b/mailboxes/boxes-lib.pl index a791989ac..0a595f7f2 100755 --- a/mailboxes/boxes-lib.pl +++ b/mailboxes/boxes-lib.pl @@ -2879,13 +2879,39 @@ if ($switched) { return $rv; } +# copy_source_dest_as_mail_user(source, dest) +# Copy a file, with perms of the user from set_mail_open_user +sub copy_source_dest_as_mail_user +{ +my ($src, $dst) = @_; +if (&should_switch_to_mail_user()) { + &open_as_mail_user(SRC, $src) || return 0; + &open_as_mail_user(DST, ">$dst") || return 0; + my $buf; + while(read(SRC, $buf, 32768) > 0) { + print DST $buf; + } + close(SRC); + close(DST); + return 1; + } +else { + return ©_source_dest($src, $dst); + } +} +# should_switch_to_mail_user() +# Returns 1 if file IO will be done as a mail owner user +sub should_switch_to_mail_user +{ +return defined($main::mail_open_user) && !$< && !$>; +} # switch_to_mail_user() # Sets the permissions used for reading files sub switch_to_mail_user { -if (defined($main::mail_open_user) && !$< && !$>) { +if (&should_switch_to_mail_user()) { # Switch file permissions to the correct user my @uinfo = $main::mail_open_user =~ /^\d+$/ ? getpwuid($main::mail_open_user) : diff --git a/mailboxes/folders-lib.pl b/mailboxes/folders-lib.pl index a5c175814..7671c2427 100755 --- a/mailboxes/folders-lib.pl +++ b/mailboxes/folders-lib.pl @@ -1300,16 +1300,15 @@ if ($folder->{'sortable'}) { sub mailbox_copy_folder { local ($src, $dest) = @_; -# XXX user permissions fix needed -&switch_to_folder_user($src); +&switch_to_folder_user($dest); if ($src->{'type'} == 0 && $dest->{'type'} == 0) { # mbox to mbox .. just read and write the files &open_as_mail_user(SOURCE, $src->{'file'}); - &open_tempfile_as_mail_user(DEST, ">>$dest->{'file'}"); - while(read(SOURCE, $buf, 1024) > 0) { - &print_tempfile(DEST, $buf); + &open_as_mail_user(DEST, ">>$dest->{'file'}"); + while(read(SOURCE, $buf, 32768) > 0) { + print DEST $buf; } - &close_tempfile_as_mail_user(DEST); + close(DEST); close(SOURCE); } elsif ($src->{'type'} == 1 && $dest->{'type'} == 1) { @@ -1317,24 +1316,24 @@ elsif ($src->{'type'} == 1 && $dest->{'type'} == 1) { local @files = &get_maildir_files($src->{'file'}); foreach my $f (@files) { local $fn = &unique_maildir_filename($dest); - ©_source_dest($f, "$dest->{'file'}/$fn"); + ©_source_dest_as_mail_user($f, "$dest->{'file'}/$fn"); } &mailbox_fix_permissions($dest); } elsif ($src->{'type'} == 1 && $dest->{'type'} == 0) { # maildir to mbox .. append all the files local @files = &get_maildir_files($src->{'file'}); - &open_tempfile(DEST, ">>$dest->{'file'}"); + &open_as_mail_user(DEST, ">>$dest->{'file'}"); local $fromline = &make_from_line("webmin\@example.com")."\n"; foreach my $f (@files) { &open_as_mail_user(SOURCE, $f); - &print_tempfile("DEST", $fromline); + print DEST $fromline; while(read(SOURCE, $buf, 1024) > 0) { - &print_tempfile(DEST, $buf); + print DEST $buf; } close(SOURCE); } - &close_tempfile(DEST); + close(DEST); } else { # read in all mail and write out, in 100 message blocks @@ -1347,7 +1346,7 @@ else { &mailbox_copy_mail($src, $dest, @want); } } -&switch_from_folder_user($src); +&switch_from_folder_user($dest); } # mailbox_move_mail(&source, &dest, mail, ...) @@ -1413,8 +1412,10 @@ else { sub mailbox_fix_permissions { local ($f, $st) = @_; +return 0 if ($< != 0); # Only makes sense when running as root +return 0 if ($main::mail_open_user); # File ops are already done as the + # correct user $st ||= [ stat($f->{'file'}) ]; -return 0 if ($< != 0); # Only makes sense when running as root if ($f->{'type'} == 0) { # Set perms on a single file &set_ownership_permissions($st->[4], $st->[5], $st->[2], $f->{'file'}); @@ -3652,9 +3653,10 @@ else { sub switch_to_folder_user { my ($folder) = @_; -if ($folder->{'user'}) { +if ($folder->{'user'} && $switch_to_folder_count == 0) { &set_mail_open_user($folder->{'user'}); } +$switch_to_folder_count++; } # switch_from_folder_user(&folder) @@ -3662,7 +3664,16 @@ if ($folder->{'user'}) { sub switch_from_folder_user { my ($folder) = @_; -&clear_mail_open_user(); +if ($switch_to_folder_count) { + $switch_to_folder_count--; + if ($switch_to_folder_count == 0) { + &clear_mail_open_user(); + } + } +else { + print STDERR "switch_from_folder_user called more often ", + "than switch_to_folder_user!\n"; + } } 1;