$OpenBSD: patch-lib_Mail_SpamAssassin_Util_pm,v 1.4 2018/02/23 17:07:35 giovanni Exp $
Index: lib/Mail/SpamAssassin/Util.pm
--- lib/Mail/SpamAssassin/Util.pm.orig
+++ lib/Mail/SpamAssassin/Util.pm
@@ -62,7 +62,8 @@ BEGIN {
   @EXPORT_OK = qw(&local_tz &base64_decode &untaint_var &untaint_file_path
                   &exit_status_str &proc_status_ok &am_running_on_windows
                   &reverse_ip_address &decode_dns_question_entry
-                  &secure_tmpfile &secure_tmpdir &uri_list_canonicalize);
+                  &secure_tmpfile &secure_tmpdir &uri_list_canonicalize
+                  &get_user_groups);
 }
 
 use Mail::SpamAssassin;
@@ -108,7 +109,7 @@ BEGIN {
     if ( !$displayed_path++ ) {
       dbg("util: current PATH is: ".join($Config{'path_sep'},File::Spec->path()));
     }
-    foreach my $path (File::Spec->path()) {
+    foreach my $path (File::Spec->path(), qw(${LOCALBASE}/bin ${LOCALBASE}/sbin)) {
       my $fname = File::Spec->catfile ($path, $filename);
       if ( -f $fname ) {
         if (-x $fname) {
@@ -988,6 +989,18 @@ sub parse_content_type {
   my($charset) = $ct =~ /\bcharset\s*=\s*["']?(.*?)["']?(?:;|$)/i;
   my($name) = $ct =~ /\b(?:file)?name\s*=\s*["']?(.*?)["']?(?:;|$)/i;
 
+  # RFC 2231 section 3: Parameter Value Continuations
+  # support continuations for name values
+  #
+  if (!$name && $ct =~ /\b(?:file)?name\*0\s*=/i) {
+
+    my @name;
+    $name[$1] = $2
+      while ($ct =~ /\b(?:file)?name\*(\d+)\s*=\s*["']?(.*?)["']?(?:;|$)/ig);
+
+    $name = join "", grep defined, @name;
+  }
+
   # Get the actual MIME type out ...
   # Note: the header content may not be whitespace unfolded, so make sure the
   # REs do /s when appropriate.
@@ -1493,13 +1506,43 @@ sub receive_date {
 }
 
 ###########################################################################
+sub get_user_groups {
+  my $suid = shift;
+  dbg("get_user_groups: uid is $suid\n");
+  my ( $user, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell, $expire ) = getpwuid($suid);
+  my $rgids="$gid ";
+  while ( my($name,$pw,$gid,$members) = getgrent() ) {
+    if ( $members =~ m/\b$user\b/ ) {
+      $rgids .= "$gid ";
+      dbg("get_user_groups: added $gid ($name) to group list which is now: $rgids\n");
+    }
+  }
+  endgrent;
+  chop $rgids;
+  return ($rgids);
+}
 
+
+
 sub setuid_to_euid {
   return if (RUNNING_ON_WINDOWS);
 
   # remember the target uid, the first number is the important one
   my $touid = $>;
-
+  my $gids = get_user_groups($touid);
+  my ( $pgid, $supgs ) = split (' ',$gids,2);
+  defined $supgs or $supgs=$pgid;
+  if ($( != $pgid) {
+    # Gotta be root for any of this to work
+    $> = 0 ;
+    dbg("util: changing real primary gid from $( to $pgid and supplemental groups to $supgs to match effective uid $touid");
+    POSIX::setgid($pgid);
+    dbg("util: POSIX::setgid($pgid) set errno to $!");  
+    $! = 0;
+    $( = $pgid;
+    $) = "$pgid $supgs";
+    dbg("util: assignment  \$) = $pgid $supgs set errno to $!");  
+  }
   if ($< != $touid) {
     dbg("util: changing real uid from $< to match effective uid $touid");
     # bug 3586: kludges needed to work around platform dependent behavior assigning to $<
@@ -1574,7 +1617,7 @@ sub helper_app_pipe_open_unix {
   eval {
     # go setuid...
     setuid_to_euid();
-    dbg("util: setuid: ruid=$< euid=$>");
+    info("util: setuid: ruid=$< euid=$> rgid=$( egid=$) ");
 
     # now set up the fds.  due to some wierdness, we may have to ensure that
     # we *really* close the correct fd number, since some other code may have
