[Pkg-dspam-misc] Bug#498434: dspam.cgi's handling of opt in/out broken

Roderick Schertler roderick at argon.org
Wed Sep 10 00:01:02 UTC 2008


Package: dspam
Version: 3.6.8-8
Severity: important
Tags: patch

I've set up dspam on a system on which users have accounts but don't have
shell access.  I'd planned on letting them opt in to dspam via dspam.cgi,
but I found that it's handling of this (while it looks like it's present)
is completely broken.

Here is a patch.

--- dspam.cgi.distrib	2008-02-17 08:51:01.000000000 -0500
+++ dspam.cgi	2008-09-09 19:49:00.000000000 -0400
@@ -625,7 +625,9 @@
 
 
     } else {
-      open(FILE, ">$FILE") || do { &error("Unable to write preferences: $!"); };
+      (my $dir = $FILE) =~ s|/[^/]+\z||;
+      -d $dir || mkdir($dir, 0770) || do { &error("Unable to mkdir $dir: $!"); };
+      open(FILE, ">$FILE") || do { &error("Unable to write preferences to $FILE: $!"); };
       print FILE <<_END;
 trainingMode=$FORM{'trainingMode'}
 spamAction=$FORM{'spamAction'}
@@ -640,6 +642,7 @@
 _END
       close(FILE);
     }
+  OptInOut($FORM{'optIn'}, $FORM{'optOut'});
   redirect("$CONFIG{'ME'}?user=$FORM{'user'}&template=preferences");
   }
 
@@ -666,10 +669,13 @@
     $DATA{"C_WHITELIST"} = "CHECKED";
   }
 
+  # Check opt in/out status based on files, even when the preferences
+  # extension is in use, as this looks to be the way dspam does it.
+  
   if ($CONFIG{'OPTMODE'} eq "OUT") {
-    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . $DATA{'C_OPTOUT'} . ">Disable DSPAM filtering<br>";
+    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optOut " . (OptedOut() ? "CHECKED" : "") . ">Disable DSPAM filtering<br>";
   } elsif ($CONFIG{'OPTMODE'} eq "IN") {
-    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optIn " . $DATA{'C_OPTIN'} . ">Enable DSPAM filtering<br>";
+    $DATA{"OPTION"} = "<INPUT TYPE=CHECKBOX NAME=optIn " . (OptedIn() ? "CHECKED" : "") . ">Enable DSPAM filtering<br>";
   } else {
     $DATA{"OPTION"} = "";
   }
@@ -677,6 +683,56 @@
   &output(%DATA);
 }
 
+sub OptInOutPath {
+  my ($type) = @_;
+  return "$CONFIG{'DSPAM_HOME'}/opt-$type/" . GetSubPath($CURRENT_USER)
+		. ".dspam";
+}
+
+sub OptedInOut {
+  my ($type) = @_;
+  return -f OptInOutPath $type;
+}
+
+sub OptedIn {
+  return OptedInOut 'in';
+}
+
+sub OptedOut {
+  return OptedInOut 'out';
+}
+
+# Create or remove the opt-in or opt-out file as appropriate.
+    
+sub OptInOut {
+  my ($optIn, $optOut) = @_;
+
+  my $default_opt_in = ($CONFIG{'OPTMODE'} eq "IN");
+
+  for (["in" , $optIn ,  $default_opt_in],
+       ["out", $optOut, !$default_opt_in]) {
+    my ($type, $raw_val, $is_default) = @$_;
+    my $bool_val = ($raw_val eq 'on');
+    my $path = OptInOutPath $type;
+    my $want_file = $is_default && $bool_val;
+    my $have_file = stat $path;
+    #warn "path=$path want_file=$want_file have_file=$have_file\n";
+    if ($want_file xor $have_file) {
+      if ($want_file) {
+	if (!open my $fh, ">>", $path) {
+	  &error("Unable to create $path: $!");
+	} else {
+	  close $fh;
+	}
+      } else {
+	if (!unlink $path) {
+	  &error("Unable to remove $path: $!");
+	}
+      }
+    }
+  }
+}
+
 #
 # Quarantine Functions
 #
@@ -1523,7 +1579,7 @@
   return $h;
 }
 
-sub GetPath {
+sub GetSubPath {
   my($USER) = @_;
   my($PATH);
 
@@ -1535,22 +1591,20 @@
     $VPOPDOMAIN = (split(/@/, $USER))[1];
     $VPOPDOMAIN = "local" if ($VPOPDOMAIN eq "");
 
-    $PATH = "$CONFIG{'DSPAM_HOME'}/data/$VPOPDOMAIN/$VPOPUSERNAME/" .
-            "$VPOPUSERNAME";
+    $PATH = "$VPOPDOMAIN/$VPOPUSERNAME";
     return $PATH;
 
   # Normal scale
   } elsif ($CONFIG{'LARGE_SCALE'} == 0) {
-    $PATH = "$CONFIG{'DSPAM_HOME'}/data/$USER/$USER";
+    $PATH = $USER;
     return $PATH;
                                                                                 
   # Large-scale
   } else {
     if (length($USER)>1) {
-      $PATH = "$CONFIG{'DSPAM_HOME'}/data/" . substr($USER, 0, 1) .
-        "/". substr($USER, 1, 1) . "/$USER/$USER";
+      $PATH = substr($USER, 0, 1) . "/". substr($USER, 1, 1) . "/$USER";
     } else {
-      $PATH = "$CONFIG{'DSPAM_HOME'}/data/$USER/$USER";
+      $PATH = $USER;
     }
     return $PATH;
   }
@@ -1558,6 +1612,11 @@
   &error("Unable to determine filesystem scale");
 }
 
+sub GetPath {
+  my($USER) = @_;
+
+  return "$CONFIG{'DSPAM_HOME'}/data/" . GetSubPath($USER) . "/$USER";
+}
 
 sub GetPrefs {
   my(%PREFS);

-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (870, 'stable'), (700, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-6-686-bigmem
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)

Versions of packages dspam depends on:
ii  libc6                       2.7-10       GNU C Library: Shared libraries
ii  libdspam7                   3.6.8-5etch1 DSPAM is a scalable and statistica
ii  libldap-2.4-2               2.4.7-6.1    OpenLDAP libraries
ii  procmail                    3.22-16      Versatile e-mail processor

Versions of packages dspam recommends:
ii  clamav-daemon      0.93.1.dfsg-volatile1 anti-virus utility for Unix - scan
ii  dspam-doc          3.6.8-5etch1          Documentation for dspam

-- no debconf information

-- 
Roderick Schertler
roderick at argon.org





More information about the Pkg-dspam-misc mailing list