All of lore.kernel.org
 help / color / mirror / Atom feed
* [mlmmj] Subscribers management in php-admin
@ 2012-02-27 21:50 Marc MAURICE
  2012-02-28  9:25 ` Thomas Goirand
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Marc MAURICE @ 2012-02-27 21:50 UTC (permalink / raw)
  To: mlmmj

[-- Attachment #1: Type: text/plain, Size: 503 bytes --]

Hello mlmmj team,

Here is a patch I made to add simple subscribers management in the 
php-admin interface.

I added some lines in php-admin README file in order to fix some 
permission issues. Those issues might also
be relevant for the perl version.

I also suggest you to add a log_error line in subscriberfuncs.c. Without 
it we have no clue about what is wrong when mlmmj is not able to read 
subdir files.

Feel free to adapt my patch if needed.

Thanks for providing mlmmj to us !

Regards,
Marc

[-- Attachment #2: patches.txt --]
[-- Type: text/plain, Size: 5742 bytes --]

diff -r 3168aed4b01a contrib/web/php-admin/README
--- a/contrib/web/php-admin/README	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/README	Mon Feb 27 22:41:56 2012 +0100
@@ -22,8 +22,19 @@
    you need to create a group (eg. mlmmj) and add both users to it. The
    subscribers.d directory then needs to be writable by that group:
 
+     # addgroup mlmmj
+     # adduser wwwrun mlmmj
+     # adduser mailuser mlmmj
      # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d/
      # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d/
+     # chmod g+s /var/spool/mlmmj/mlmmj-test/subscribers.d/
+
+   setgid flag is needed when the webserver calls mlmmj-sub and creates a file
+   under subscribers.d, to keep the mlmmj group.
+
+   If using the Exim mailserver, you should add initgroups = true in your
+   mlmmj_transport, otherwise it won't be able to write files having write
+   permission to mlmmj group.
 
 5) To enable access control on Apache you have to rename dot.htaccess to
    .htaccess and edit the path inside the file to point to a htpasswd file
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/index.php
--- a/contrib/web/php-admin/htdocs/index.php	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/htdocs/index.php	Mon Feb 27 22:41:56 2012 +0100
@@ -35,15 +35,16 @@
 
 $lists = "";
 
-$dir = opendir($topdir);
-while ($file = readdir($dir)) {
+# use scandir to have alphabetical order
+foreach (scandir($topdir) as $file) {
     if (!ereg("^\.",$file))
     {
-	$lists .= "<a href=\"edit.php?list=".urlencode($file)."\">".
-	    htmlentities($file)."</a><br />\n";
+	$lists .= "<p>".htmlentities($file)."<br/>
+<a href=\"edit.php?list=".urlencode($file)."\">Config</a> - <a href=\"subscribers.php?list=".urlencode($file)."\">Subscribers</a>
+</p>
+";
     }
 }
-closedir($dir); 
 
 $tpl->assign(array("LISTS" => $lists));
 
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/subscribers.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/htdocs/subscribers.php	Mon Feb 27 22:41:56 2012 +0100
@@ -0,0 +1,86 @@
+<?php
+
+# show errors like permission denied...
+ini_set('display_errors',1);
+
+require(dirname(dirname(__FILE__))."/conf/config.php");
+require(dirname(__FILE__)."/class.rFastTemplate.php");
+
+$tpl = new rFastTemplate($templatedir);
+
+# get the list parameter and check that list exists
+$list = $_GET["list"];
+
+if(!isset($list))
+die("no list specified");
+
+if (dirname(realpath($topdir."/".$list)) != realpath($topdir))
+die("list outside topdir");
+
+if(!is_dir($topdir."/".$list))
+die("non-existent list");
+
+# this will be displayed on the to of the page
+$message = "";
+
+# subscribe some people if tosubscribe is set
+if (isset($_POST["tosubscribe"])) {
+	
+	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
+		$email = trim($line);
+		if ($email != "") {
+			$cmd = "/usr/bin/mlmmj-sub -L /var/spool/mlmmj/$list -a '$email' 2>&1";
+			exec($cmd, $out, $ret);
+			if ($ret !== 0) {
+				$message.= "Subscribe error for $email <!--cmd=$cmd out=".implode($out)." ret=$ret--> <br/>";
+			}
+		}
+		
+	}
+
+# delete some people if delete is set
+} else if (isset($_POST["delete"])) {
+
+	$email = $_POST["email"];
+	$cmd = "/usr/bin/mlmmj-unsub -L /var/spool/mlmmj/$list -a '$email' 2>&1";
+	exec($cmd, $out, $ret);
+	if ($ret !== 0) {
+		$message = "Unsubscribe error. cmd=$cmd out=".implode($out)." ret=$ret";
+	}
+}
+
+$subscribers="";
+
+# get subscribers from mlmmj
+$cmd = "/usr/bin/mlmmj-list -L /var/spool/mlmmj/$list 2>&1";
+exec($cmd, $out, $ret);
+if ($ret !== 0) {
+	$message.= "Error: Could not get subscribers list.";
+}
+
+foreach ($out as $email) {
+	$email = trim($email);
+
+	$form = "<form action=\"subscribers.php?list=$list\" method=\"post\" style=\"margin: 0; margin-left: 1em\">";
+	$form.= "<input type=\"hidden\" name=\"email\" value=\"".htmlspecialchars($email)."\" />";
+	$form.= "<input type=\"submit\" name=\"delete\" value=\"Remove\" />";
+	$form.= "</form>";
+
+	$subscribers.= "<tr><td>".htmlspecialchars($email)."</td><td>$form</td></tr>\n";
+}
+
+if ($subscribers === "") {
+	$subscribers = "<tr><td>This list is empty.</td></tr>\n";
+}
+
+# set template vars
+$tpl->define(array("main" => "subscribers.html"));
+
+$tpl->assign(array("LIST" => $list));
+$tpl->assign(array("MESSAGE" => "</p>$message</p>"));
+$tpl->assign(array("SUBS" => $subscribers));
+
+$tpl->parse("MAIN","main");
+$tpl->FastPrint("MAIN");
+
+?>
diff -r 3168aed4b01a contrib/web/php-admin/templates/subscribers.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/templates/subscribers.html	Mon Feb 27 22:41:56 2012 +0100
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>mlmmj - {LIST} subscribers</title>
+<style type="text/css">
+#subscribers {
+	float: left;
+}
+
+#addsubscribers {
+        float: left;
+	margin-left: 2em;
+}
+#index {
+	clear: both;
+}
+</style>
+</head>
+<body>
+<h1>{LIST} subscribers</h1>
+
+{MESSAGE}
+
+<table id="subscribers">
+{SUBS}
+</table>
+
+<form method="post" action="subscribers.php?list={LIST}" id="addsubscribers">
+Add subscribers:<br/>
+<textarea name="tosubscribe" rows="5" cols="30">
+</textarea><br/>
+<input type="submit" name="submit" value="Add" />
+</form>
+
+<p id="index">
+<a href="index.php">Index</a>
+</p>
+</body>
+</html>
diff -r 3168aed4b01a src/subscriberfuncs.c
--- a/src/subscriberfuncs.c	Wed Feb 22 00:11:07 2012 +1100
+++ b/src/subscriberfuncs.c	Mon Feb 27 22:41:56 2012 +0100
@@ -132,6 +132,7 @@
 		subreadname = concatstr(2, subddirname, dp->d_name);
 		subread = open(subreadname, O_RDONLY);
 		if(subread < 0) {
+	                log_error(LOG_ARGS, "Could not open %s", subreadname);
 			myfree(subreadname);
 			continue;
 		}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
@ 2012-02-28  9:25 ` Thomas Goirand
  2012-02-28  9:47 ` Marc MAURICE
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Thomas Goirand @ 2012-02-28  9:25 UTC (permalink / raw)
  To: mlmmj

On 02/28/2012 05:50 AM, Marc MAURICE wrote:
> +} else if (isset($_POST["delete"])) {
> +
> +	$email = $_POST["email"];
> +	$cmd = "/usr/bin/mlmmj-unsub -L /var/spool/mlmmj/$list -a '$email' 2>&1";

What if $email contains:

'; rm -rf /

Please don't accept such a weak code. At least, a minimum check on the
validity of $email variable content should be made. In fact, and
generally speaking, absolutely *all* input variables should be checked.

Thomas


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
  2012-02-28  9:25 ` Thomas Goirand
@ 2012-02-28  9:47 ` Marc MAURICE
  2012-02-28 14:29 ` Ben Schmidt
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Marc MAURICE @ 2012-02-28  9:47 UTC (permalink / raw)
  To: mlmmj

I agree with you Thomas.
I forgot the check because the interface is http auth restricted, but 
this is not not an excuse.

We should also fix the existing code in save.php.

Marc


Le 28/02/2012 10:25, Thomas Goirand a écrit :
> On 02/28/2012 05:50 AM, Marc MAURICE wrote:
>> +} else if (isset($_POST["delete"])) {
>> +
>> +	$email = $_POST["email"];
>> +	$cmd = "/usr/bin/mlmmj-unsub -L /var/spool/mlmmj/$list -a '$email' 2>&1";
> What if $email contains:
>
> '; rm -rf /
>
> Please don't accept such a weak code. At least, a minimum check on the
> validity of $email variable content should be made. In fact, and
> generally speaking, absolutely *all* input variables should be checked.
>
> Thomas
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
  2012-02-28  9:25 ` Thomas Goirand
  2012-02-28  9:47 ` Marc MAURICE
@ 2012-02-28 14:29 ` Ben Schmidt
  2012-02-29  3:09 ` Thomas Goirand
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Ben Schmidt @ 2012-02-28 14:29 UTC (permalink / raw)
  To: mlmmj

On 28/02/12 8:25 PM, Thomas Goirand wrote:
> On 02/28/2012 05:50 AM, Marc MAURICE wrote:
>> +} else if (isset($_POST["delete"])) {
>> +
>> +	$email = $_POST["email"];
>> +	$cmd = "/usr/bin/mlmmj-unsub -L /var/spool/mlmmj/$list -a '$email' 2>&1";
>
> What if $email contains:
>
> '; rm -rf /
>
> Please don't accept such a weak code. At least, a minimum check on the
> validity of $email variable content should be made. In fact, and
> generally speaking, absolutely *all* input variables should be checked.

And indeed, since ' is a valid character in an email address, the value
will have to be properly escaped when passed to the shell, not just
validated.

It wouldn't surprise me if some of the other PHP code is wrong, too.

Please do throw some good patches my way and I'll get them in. These
kinds of validation fixes are worth getting into a release as soon as
possible.

The extra functionality will go in too, but perhaps not into the next
release unless I get it very soon. (I finished implementation for the
next release tonight, so in a day or two, after a little testing, I'll
release an alpha and declare feature-freeze.)

Ben.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (2 preceding siblings ...)
  2012-02-28 14:29 ` Ben Schmidt
@ 2012-02-29  3:09 ` Thomas Goirand
  2012-02-29  3:57 ` Ben Schmidt
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Thomas Goirand @ 2012-02-29  3:09 UTC (permalink / raw)
  To: mlmmj

On 02/28/2012 05:47 PM, Marc MAURICE wrote:
> I agree with you Thomas.
> I forgot the check because the interface is http auth restricted, but
> this is not not an excuse.
> 
> We should also fix the existing code in save.php.
> 
> Marc

Not only this. You should check for the variable validity, with a
regular expression like this one for example:
$reg = "/(^([a-zA-Z0-9])|^([a-zA-Z0-9]+)([._a-zA-Z0-9-]*))@
([a-z0-9]+)([-a-z0-9.]*)\.([a-z0-9-]*)([a-z0-9]+)\$/";

(note that you should remove the \n after the @)

but you should *also* use escapeshellarg():
http://www.php.net/manual/en/function.escapeshellarg.php



As for the save.php, I also found some very silly piece of code like
this one:
// Perl's encode_entities (to be able to use tunables.pl)
function encode_entities($str) { return htmlentities($str); }

I'd like someone to explain to me why htmlentities() has to be wrapped
like this... :)

Then, there's things like this which worries me:
fwrite($fp, $HTTP_POST_VARS[$name]);

Not only the variable should be checked, but also, if I'm not mistaking,
$HTTP_POST_VARS is deprecated, and maybe even *removed* (I didn't check)
from php 5.4, which is going to reach Debian SID in a mater of weeks now
(we should be using $_POST instead).

Functions like mlmmj_boolean() has parameters that it isn't using, so
it's weird.

So yes, all this needs a code review... :)

Thomas


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (3 preceding siblings ...)
  2012-02-29  3:09 ` Thomas Goirand
@ 2012-02-29  3:57 ` Ben Schmidt
  2012-03-01 13:08 ` Marc MAURICE
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Ben Schmidt @ 2012-02-29  3:57 UTC (permalink / raw)
  To: mlmmj

> As for the save.php, I also found some very silly piece of code like
> this one:
> // Perl's encode_entities (to be able to use tunables.pl)
> function encode_entities($str) { return htmlentities($str); }
>
> I'd like someone to explain to me why htmlentities() has to be wrapped
> like this... :)

For exactly the reason in the code comment: it's so that tunables.pl can
be used. The PHP file evaluates the tunables.pl (Perl) file as if it
were a PHP file. The tunables.pl file uses the Perl function
encode_entities(), so to make it work, a function of that name is
defined in PHP that just calls the equivalent PHP function. The benefit
is that only one tunables.pl file needs to be maintained, not a
tunables.pl and a tunables.php.

> Then, there's things like this which worries me:
> fwrite($fp, $HTTP_POST_VARS[$name]);
>
> Not only the variable should be checked, but also, if I'm not mistaking,
> $HTTP_POST_VARS is deprecated, and maybe even *removed* (I didn't check)
> from php 5.4, which is going to reach Debian SID in a mater of weeks now
> (we should be using $_POST instead).

This was at least partly fixed ages ago in version control, so you
evidently didn't check the current state of Mlmmj either. :-)

> Functions like mlmmj_boolean() has parameters that it isn't using, so
> it's weird.
>
> So yes, all this needs a code review... :)

Never hurts.

Ben.





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (4 preceding siblings ...)
  2012-02-29  3:57 ` Ben Schmidt
@ 2012-03-01 13:08 ` Marc MAURICE
  2012-03-01 15:07 ` Thomas Goirand
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Marc MAURICE @ 2012-03-01 13:08 UTC (permalink / raw)
  To: mlmmj

[-- Attachment #1: Type: text/plain, Size: 1628 bytes --]

Hello,

A new patch using
filter_var($email, FILTER_VALIDATE_EMAIL)
and escapeshellarg().

Marc



Le 29/02/2012 04:57, Ben Schmidt a écrit :
>> As for the save.php, I also found some very silly piece of code like
>> this one:
>> // Perl's encode_entities (to be able to use tunables.pl)
>> function encode_entities($str) { return htmlentities($str); }
>>
>> I'd like someone to explain to me why htmlentities() has to be wrapped
>> like this... :)
>
> For exactly the reason in the code comment: it's so that tunables.pl can
> be used. The PHP file evaluates the tunables.pl (Perl) file as if it
> were a PHP file. The tunables.pl file uses the Perl function
> encode_entities(), so to make it work, a function of that name is
> defined in PHP that just calls the equivalent PHP function. The benefit
> is that only one tunables.pl file needs to be maintained, not a
> tunables.pl and a tunables.php.
>
>> Then, there's things like this which worries me:
>> fwrite($fp, $HTTP_POST_VARS[$name]);
>>
>> Not only the variable should be checked, but also, if I'm not mistaking,
>> $HTTP_POST_VARS is deprecated, and maybe even *removed* (I didn't check)
>> from php 5.4, which is going to reach Debian SID in a mater of weeks now
>> (we should be using $_POST instead).
>
> This was at least partly fixed ages ago in version control, so you
> evidently didn't check the current state of Mlmmj either. :-)
>
>> Functions like mlmmj_boolean() has parameters that it isn't using, so
>> it's weird.
>>
>> So yes, all this needs a code review... :)
>
> Never hurts.
>
> Ben.
>
>
>
>
>

[-- Attachment #2: patches2.txt --]
[-- Type: text/plain, Size: 6068 bytes --]

diff -r 3168aed4b01a contrib/web/php-admin/README
--- a/contrib/web/php-admin/README	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/README	Thu Mar 01 14:03:42 2012 +0100
@@ -22,8 +22,19 @@
    you need to create a group (eg. mlmmj) and add both users to it. The
    subscribers.d directory then needs to be writable by that group:
 
+     # addgroup mlmmj
+     # adduser wwwrun mlmmj
+     # adduser mailuser mlmmj
      # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d/
      # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d/
+     # chmod g+s /var/spool/mlmmj/mlmmj-test/subscribers.d/
+
+   setgid flag is needed when the webserver calls mlmmj-sub and creates a file
+   under subscribers.d, to keep the mlmmj group.
+
+   If using the Exim mailserver, you should add initgroups = true in your
+   mlmmj_transport, otherwise it won't be able to write files having write
+   permission to mlmmj group.
 
 5) To enable access control on Apache you have to rename dot.htaccess to
    .htaccess and edit the path inside the file to point to a htpasswd file
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/index.php
--- a/contrib/web/php-admin/htdocs/index.php	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/htdocs/index.php	Thu Mar 01 14:03:42 2012 +0100
@@ -35,15 +35,16 @@
 
 $lists = "";
 
-$dir = opendir($topdir);
-while ($file = readdir($dir)) {
+# use scandir to have alphabetical order
+foreach (scandir($topdir) as $file) {
     if (!ereg("^\.",$file))
     {
-	$lists .= "<a href=\"edit.php?list=".urlencode($file)."\">".
-	    htmlentities($file)."</a><br />\n";
+	$lists .= "<p>".htmlentities($file)."<br/>
+<a href=\"edit.php?list=".urlencode($file)."\">Config</a> - <a href=\"subscribers.php?list=".urlencode($file)."\">Subscribers</a>
+</p>
+";
     }
 }
-closedir($dir); 
 
 $tpl->assign(array("LISTS" => $lists));
 
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/subscribers.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/htdocs/subscribers.php	Thu Mar 01 14:03:42 2012 +0100
@@ -0,0 +1,92 @@
+<?php
+
+# show errors like permission denied...
+ini_set('display_errors',1);
+
+require(dirname(dirname(__FILE__))."/conf/config.php");
+require(dirname(__FILE__)."/class.rFastTemplate.php");
+
+$tpl = new rFastTemplate($templatedir);
+
+# get the list parameter and check that list exists
+$list = $_GET["list"];
+
+if(!isset($list))
+die("no list specified");
+
+if (dirname(realpath($topdir."/".$list)) != realpath($topdir))
+die("list outside topdir");
+
+if(!is_dir($topdir."/".$list))
+die("non-existent list");
+
+# this will be displayed on the to of the page
+$message = "";
+
+# subscribe some people if tosubscribe is set
+if (isset($_POST["tosubscribe"])) {
+	
+	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
+		$email = trim($line);
+		if ($email != "") {
+			if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
+				$cmd = "/usr/bin/mlmmj-sub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a '".escapeshellarg($email)."' 2>&1";
+				exec($cmd, $out, $ret);
+				if ($ret !== 0) {
+					$message.= "Subscribe error for $email <!--cmd=$cmd out=".implode($out)." ret=$ret--> <br/>";
+				}
+			} else {
+				$message.= "Email address not valid: $email <br/>";
+			}
+		}
+		
+	}
+
+# delete some people if delete is set
+} else if (isset($_POST["delete"])) {
+
+	$email = $_POST["email"];
+	if (! filter_var($email, FILTER_VALIDATE_EMAIL)) die("Email address not valid");
+	
+	$cmd = "/usr/bin/mlmmj-unsub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a '".escapeshellarg($email)."' 2>&1";
+	exec($cmd, $out, $ret);
+	if ($ret !== 0) {
+		$message = "Unsubscribe error. cmd=$cmd out=".implode($out)." ret=$ret";
+	}
+}
+
+$subscribers="";
+
+# get subscribers from mlmmj
+$cmd = "/usr/bin/mlmmj-list -L '/var/spool/mlmmj/".escapeshellarg($list)."' 2>&1";
+exec($cmd, $out, $ret);
+if ($ret !== 0) {
+	$message.= "Error: Could not get subscribers list.";
+}
+
+foreach ($out as $email) {
+	$email = trim($email);
+
+	$form = "<form action=\"subscribers.php?list=$list\" method=\"post\" style=\"margin: 0; margin-left: 1em\">";
+	$form.= "<input type=\"hidden\" name=\"email\" value=\"".htmlspecialchars($email)."\" />";
+	$form.= "<input type=\"submit\" name=\"delete\" value=\"Remove\" />";
+	$form.= "</form>";
+
+	$subscribers.= "<tr><td>".htmlspecialchars($email)."</td><td>$form</td></tr>\n";
+}
+
+if ($subscribers === "") {
+	$subscribers = "<tr><td>This list is empty.</td></tr>\n";
+}
+
+# set template vars
+$tpl->define(array("main" => "subscribers.html"));
+
+$tpl->assign(array("LIST" => $list));
+$tpl->assign(array("MESSAGE" => "</p>$message</p>"));
+$tpl->assign(array("SUBS" => $subscribers));
+
+$tpl->parse("MAIN","main");
+$tpl->FastPrint("MAIN");
+
+?>
diff -r 3168aed4b01a contrib/web/php-admin/templates/subscribers.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/templates/subscribers.html	Thu Mar 01 14:03:42 2012 +0100
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>mlmmj - {LIST} subscribers</title>
+<style type="text/css">
+#subscribers {
+	float: left;
+}
+
+#addsubscribers {
+        float: left;
+	margin-left: 2em;
+}
+#index {
+	clear: both;
+}
+</style>
+</head>
+<body>
+<h1>{LIST} subscribers</h1>
+
+{MESSAGE}
+
+<table id="subscribers">
+{SUBS}
+</table>
+
+<form method="post" action="subscribers.php?list={LIST}" id="addsubscribers">
+Add subscribers:<br/>
+<textarea name="tosubscribe" rows="5" cols="30">
+</textarea><br/>
+<input type="submit" name="submit" value="Add" />
+</form>
+
+<p id="index">
+<a href="index.php">Index</a>
+</p>
+</body>
+</html>
diff -r 3168aed4b01a src/subscriberfuncs.c
--- a/src/subscriberfuncs.c	Wed Feb 22 00:11:07 2012 +1100
+++ b/src/subscriberfuncs.c	Thu Mar 01 14:03:42 2012 +0100
@@ -132,6 +132,7 @@
 		subreadname = concatstr(2, subddirname, dp->d_name);
 		subread = open(subreadname, O_RDONLY);
 		if(subread < 0) {
+	                log_error(LOG_ARGS, "Could not open %s", subreadname);
 			myfree(subreadname);
 			continue;
 		}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (5 preceding siblings ...)
  2012-03-01 13:08 ` Marc MAURICE
@ 2012-03-01 15:07 ` Thomas Goirand
  2012-03-02 12:59 ` Marc MAURICE
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Thomas Goirand @ 2012-03-01 15:07 UTC (permalink / raw)
  To: mlmmj

On 03/01/2012 09:08 PM, Marc MAURICE wrote:
> +if (isset($_POST["tosubscribe"])) {
> +	
> +	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
> +		$email = trim($line);
> +		if ($email != "") {
> +			if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
> +				$cmd = "/usr/bin/mlmmj-sub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a '".escapeshellarg($email)."' 2>&1";
> +				exec($cmd, $out, $ret);
> +				if ($ret != 0) {
> +					$message.= "Subscribe error for $email <!--cmd=$cmd out=".implode($out)." ret=$ret--> <br/>";
> +				}
> +			} else {
> +				$message.= "Email address not valid: $email <br/>";

If $email isn't valid, then it's even more a reason not to display it
(eg: unless you want to shoot yourself in the foot with issues like
cross site scripting...).

Also, I'm not sure what you are attempting with "displaying" the output
of the subscribing command in a HTML comment. Why not displaying it for
real, using htmlspecialchars() (which by the way, you didn't use, which
is dangerous) and ln2br() in a <pre> tag?

Thomas


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (6 preceding siblings ...)
  2012-03-01 15:07 ` Thomas Goirand
@ 2012-03-02 12:59 ` Marc MAURICE
  2012-03-04 14:05 ` Ben Schmidt
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Marc MAURICE @ 2012-03-02 12:59 UTC (permalink / raw)
  To: mlmmj

[-- Attachment #1: Type: text/plain, Size: 1466 bytes --]

Here is the new patch version.

The email should be displayed, otherwise the user will have no clue 
about which email is wrong if his email list is very long.

I put htmlspecialchars everywhere and errors are now enclosed in <pre> tags.
no need for ln2br in <pre> tags no ?

Marc


Le 01/03/2012 16:07, Thomas Goirand a écrit :
> On 03/01/2012 09:08 PM, Marc MAURICE wrote:
>> +if (isset($_POST["tosubscribe"])) {
>> +	
>> +	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
>> +		$email = trim($line);
>> +		if ($email != "") {
>> +			if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
>> +				$cmd = "/usr/bin/mlmmj-sub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a '".escapeshellarg($email)."' 2>&1";
>> +				exec($cmd, $out, $ret);
>> +				if ($ret !== 0) {
>> +					$message.= "Subscribe error for $email<!--cmd=$cmd out=".implode($out)." ret=$ret-->  <br/>";
>> +				}
>> +			} else {
>> +				$message.= "Email address not valid: $email<br/>";
> If $email isn't valid, then it's even more a reason not to display it
> (eg: unless you want to shoot yourself in the foot with issues like
> cross site scripting...).
>
> Also, I'm not sure what you are attempting with "displaying" the output
> of the subscribing command in a HTML comment. Why not displaying it for
> real, using htmlspecialchars() (which by the way, you didn't use, which
> is dangerous) and ln2br() in a<pre>  tag?
>
> Thomas
>
>

[-- Attachment #2: patches3.txt --]
[-- Type: text/plain, Size: 6202 bytes --]

diff -r 3168aed4b01a contrib/web/php-admin/README
--- a/contrib/web/php-admin/README	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/README	Fri Mar 02 13:54:31 2012 +0100
@@ -22,8 +22,19 @@
    you need to create a group (eg. mlmmj) and add both users to it. The
    subscribers.d directory then needs to be writable by that group:
 
+     # addgroup mlmmj
+     # adduser wwwrun mlmmj
+     # adduser mailuser mlmmj
      # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d/
      # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d/
+     # chmod g+s /var/spool/mlmmj/mlmmj-test/subscribers.d/
+
+   setgid flag is needed when the webserver calls mlmmj-sub and creates a file
+   under subscribers.d, to keep the mlmmj group.
+
+   If using the Exim mailserver, you should add initgroups = true in your
+   mlmmj_transport, otherwise it won't be able to write files having write
+   permission to mlmmj group.
 
 5) To enable access control on Apache you have to rename dot.htaccess to
    .htaccess and edit the path inside the file to point to a htpasswd file
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/index.php
--- a/contrib/web/php-admin/htdocs/index.php	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/htdocs/index.php	Fri Mar 02 13:54:31 2012 +0100
@@ -35,15 +35,16 @@
 
 $lists = "";
 
-$dir = opendir($topdir);
-while ($file = readdir($dir)) {
+# use scandir to have alphabetical order
+foreach (scandir($topdir) as $file) {
     if (!ereg("^\.",$file))
     {
-	$lists .= "<a href=\"edit.php?list=".urlencode($file)."\">".
-	    htmlentities($file)."</a><br />\n";
+	$lists .= "<p>".htmlentities($file)."<br/>
+<a href=\"edit.php?list=".urlencode($file)."\">Config</a> - <a href=\"subscribers.php?list=".urlencode($file)."\">Subscribers</a>
+</p>
+";
     }
 }
-closedir($dir); 
 
 $tpl->assign(array("LISTS" => $lists));
 
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/subscribers.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/htdocs/subscribers.php	Fri Mar 02 13:54:31 2012 +0100
@@ -0,0 +1,93 @@
+<?php
+
+# show errors like permission denied...
+ini_set('display_errors',1);
+
+require(dirname(dirname(__FILE__))."/conf/config.php");
+require(dirname(__FILE__)."/class.rFastTemplate.php");
+
+$tpl = new rFastTemplate($templatedir);
+
+# get the list parameter and check that list exists
+$list = $_GET["list"];
+
+if(!isset($list))
+die("no list specified");
+
+if (dirname(realpath($topdir."/".$list)) != realpath($topdir))
+die("list outside topdir");
+
+if(!is_dir($topdir."/".$list))
+die("non-existent list");
+
+# this will be displayed on the top of the page
+$message = "";
+
+# subscribe some people if tosubscribe is set
+if (isset($_POST["tosubscribe"])) {
+	
+	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
+		$email = trim($line);
+		if ($email != "") {
+			if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
+				$cmd = "/usr/bin/mlmmj-sub -L ".escapeshellarg("/var/spool/mlmmj/$list")." -a ".escapeshellarg($email)." 2>&1";
+				exec($cmd, $out, $ret);
+				if ($ret !== 0) {
+					$message.= "* Subscribe error for $email\ncommand: $cmd\nreturn code: $ret\noutput: ".implode("\n", $out)."\n";
+				}
+			} else {
+				$message.= "* Email address not valid: $email\n";
+			}
+		}
+		
+	}
+
+# delete some people if delete is set
+} else if (isset($_POST["delete"])) {
+
+	$email = $_POST["email"];
+	if (! filter_var($email, FILTER_VALIDATE_EMAIL)) die("Email address not valid");
+	
+	$cmd = "/usr/bin/mlmmj-unsub -L ".escapeshellarg("/var/spool/mlmmj/$list")." -a ".escapeshellarg($email)." 2>&1";
+	exec($cmd, $out, $ret);
+	if ($ret !== 0) {
+		$message.= "* Unsubscribe error.\ncommand: $cmd\nreturn code: $ret\noutput: ".implode("\n", $out)."\n";
+	}
+}
+
+$subscribers="";
+
+# get subscribers from mlmmj
+$cmd = "/usr/bin/mlmmj-list -L ".escapeshellarg("/var/spool/mlmmj/$list")." 2>&1";
+exec($cmd, $out, $ret);
+if ($ret !== 0) {
+	$message.= "* Error: Could not get subscribers list.\n";
+} else {
+
+	foreach ($out as $email) {
+		$email = trim($email);
+
+		$form = "<form action=\"subscribers.php?list=".htmlspecialchars($list)."\" method=\"post\" style=\"margin: 0; margin-left: 1em\">";
+		$form.= "<input type=\"hidden\" name=\"email\" value=\"".htmlspecialchars($email)."\" />";
+		$form.= "<input type=\"submit\" name=\"delete\" value=\"Remove\" />";
+		$form.= "</form>";
+
+		$subscribers.= "<tr><td>".htmlspecialchars($email)."</td><td>$form</td></tr>\n";
+	}
+
+	if ($subscribers === "") {
+		$subscribers = "<tr><td>This list is empty.</td></tr>\n";
+	}
+}
+
+# set template vars
+$tpl->define(array("main" => "subscribers.html"));
+
+$tpl->assign(array("LIST" => htmlspecialchars($list)));
+$tpl->assign(array("MESSAGE" => "<pre>".htmlspecialchars($message)."</pre>"));
+$tpl->assign(array("SUBS" => $subscribers));
+
+$tpl->parse("MAIN","main");
+$tpl->FastPrint("MAIN");
+
+?>
diff -r 3168aed4b01a contrib/web/php-admin/templates/subscribers.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/templates/subscribers.html	Fri Mar 02 13:54:31 2012 +0100
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>mlmmj - {LIST} subscribers</title>
+<style type="text/css">
+#subscribers {
+	float: left;
+}
+
+#addsubscribers {
+        float: left;
+	margin-left: 2em;
+}
+#index {
+	clear: both;
+}
+</style>
+</head>
+<body>
+<h1>{LIST} subscribers</h1>
+
+{MESSAGE}
+
+<table id="subscribers">
+{SUBS}
+</table>
+
+<form method="post" action="subscribers.php?list={LIST}" id="addsubscribers">
+Add subscribers:<br/>
+<textarea name="tosubscribe" rows="5" cols="30">
+</textarea><br/>
+<input type="submit" name="submit" value="Add" />
+</form>
+
+<p id="index">
+<a href="index.php">Index</a>
+</p>
+</body>
+</html>
diff -r 3168aed4b01a src/subscriberfuncs.c
--- a/src/subscriberfuncs.c	Wed Feb 22 00:11:07 2012 +1100
+++ b/src/subscriberfuncs.c	Fri Mar 02 13:54:31 2012 +0100
@@ -132,6 +132,7 @@
 		subreadname = concatstr(2, subddirname, dp->d_name);
 		subread = open(subreadname, O_RDONLY);
 		if(subread < 0) {
+	                log_error(LOG_ARGS, "Could not open %s", subreadname);
 			myfree(subreadname);
 			continue;
 		}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (7 preceding siblings ...)
  2012-03-02 12:59 ` Marc MAURICE
@ 2012-03-04 14:05 ` Ben Schmidt
  2012-03-05 12:02 ` Marc MAURICE
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Ben Schmidt @ 2012-03-04 14:05 UTC (permalink / raw)
  To: mlmmj

Thanks for your contribution. The patch is getting better, but here are
some further review comments:

- You have added new files; could they have headers clarifying their
   license, please?
- /var/spool/mlmmj should not be hardcoded; you should use $topdir.
- You need to unset($out) before calling exec(...,$out,...); see the PHP
   documentation for exec().
- Please don't ini_set display_errors to true; that could expose details
   that the server administrator does not want to expose; admins should
   have their PHP logging set up adequately to give them what they need,
   or can change ini settings themselves if they need to.
- Could you concatenate strings and use \n for linebreaks, please,
   maintaining the indent in the PHP script, instead of having string
   literals that span multiple lines?
- Could you consider extending this slightly to allow subscription of
   digesters and nomailers? (Update the README, too, to get permissions
   set correctly on all relevant directories.) This could be a separate
   patch, or omitted, but it would be nice.

And yes, of course inside <pre> ln2br is unnecessary.

Cheers,

Ben.



On 2/03/12 11:59 PM, Marc MAURICE wrote:
> Here is the new patch version.
>
> The email should be displayed, otherwise the user will have no clue about which
> email is wrong if his email list is very long.
>
> I put htmlspecialchars everywhere and errors are now enclosed in <pre> tags.
> no need for ln2br in <pre> tags no ?
>
> Marc
>
>
> Le 01/03/2012 16:07, Thomas Goirand a écrit :
>> On 03/01/2012 09:08 PM, Marc MAURICE wrote:
>>> +if (isset($_POST["tosubscribe"])) {
>>> +
>>> + foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
>>> + $email = trim($line);
>>> + if ($email != "") {
>>> + if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
>>> + $cmd = "/usr/bin/mlmmj-sub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a
>>> '".escapeshellarg($email)."' 2>&1";
>>> + exec($cmd, $out, $ret);
>>> + if ($ret != 0) {
>>> + $message.= "Subscribe error for $email<!--cmd=$cmd out=".implode($out)."
>>> ret=$ret--> <br/>";
>>> + }
>>> + } else {
>>> + $message.= "Email address not valid: $email<br/>";
>> If $email isn't valid, then it's even more a reason not to display it
>> (eg: unless you want to shoot yourself in the foot with issues like
>> cross site scripting...).
>>
>> Also, I'm not sure what you are attempting with "displaying" the output
>> of the subscribing command in a HTML comment. Why not displaying it for
>> real, using htmlspecialchars() (which by the way, you didn't use, which
>> is dangerous) and ln2br() in a<pre> tag?
>>
>> Thomas
>>
>>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (8 preceding siblings ...)
  2012-03-04 14:05 ` Ben Schmidt
@ 2012-03-05 12:02 ` Marc MAURICE
  2012-03-06  8:45 ` Mads Martin Jørgensen
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Marc MAURICE @ 2012-03-05 12:02 UTC (permalink / raw)
  To: mlmmj

[-- Attachment #1: Type: text/plain, Size: 3122 bytes --]

Hello Ben,

Here is the new patch.

> - You have added new files; could they have headers clarifying their
>   license, please?
license added to subscribers.php
> - /var/spool/mlmmj should not be hardcoded; you should use $topdir.
done
> - You need to unset($out) before calling exec(...,$out,...); see the PHP
>   documentation for exec().
done
> - Please don't ini_set display_errors to true; that could expose details
>   that the server administrator does not want to expose; admins should
>   have their PHP logging set up adequately to give them what they need,
>   or can change ini settings themselves if they need to.
deleted
> - Could you concatenate strings and use \n for linebreaks, please,
>   maintaining the indent in the PHP script, instead of having string
>   literals that span multiple lines?
done in index.php
> - Could you consider extending this slightly to allow subscription of
>   digesters and nomailers? (Update the README, too, to get permissions
>   set correctly on all relevant directories.) This could be a separate
>   patch, or omitted, but it would be nice.
Yes, it would be better in a new patch.
I will try to find some time to work on it next days.

Ho I have on question : what is the main purpose of nomailers ?
I understand that those people do not get any list mail.
Is it to be able to post to a list without receiving mail with subonlypost ?

I did not find anything about it in the doc.

Thanks in advance,

Marc



>
>
>
>
> On 2/03/12 11:59 PM, Marc MAURICE wrote:
>> Here is the new patch version.
>>
>> The email should be displayed, otherwise the user will have no clue 
>> about which
>> email is wrong if his email list is very long.
>>
>> I put htmlspecialchars everywhere and errors are now enclosed in 
>> <pre> tags.
>> no need for ln2br in <pre> tags no ?
>>
>> Marc
>>
>>
>> Le 01/03/2012 16:07, Thomas Goirand a écrit :
>>> On 03/01/2012 09:08 PM, Marc MAURICE wrote:
>>>> +if (isset($_POST["tosubscribe"])) {
>>>> +
>>>> + foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as 
>>>> $line) {
>>>> + $email = trim($line);
>>>> + if ($email != "") {
>>>> + if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
>>>> + $cmd = "/usr/bin/mlmmj-sub -L 
>>>> '/var/spool/mlmmj/".escapeshellarg($list)."' -a
>>>> '".escapeshellarg($email)."' 2>&1";
>>>> + exec($cmd, $out, $ret);
>>>> + if ($ret !== 0) {
>>>> + $message.= "Subscribe error for $email<!--cmd=$cmd 
>>>> out=".implode($out)."
>>>> ret=$ret--> <br/>";
>>>> + }
>>>> + } else {
>>>> + $message.= "Email address not valid: $email<br/>";
>>> If $email isn't valid, then it's even more a reason not to display it
>>> (eg: unless you want to shoot yourself in the foot with issues like
>>> cross site scripting...).
>>>
>>> Also, I'm not sure what you are attempting with "displaying" the output
>>> of the subscribing command in a HTML comment. Why not displaying it for
>>> real, using htmlspecialchars() (which by the way, you didn't use, which
>>> is dangerous) and ln2br() in a<pre> tag?
>>>
>>> Thomas
>>>
>>>

[-- Attachment #2: patches3.txt --]
[-- Type: text/plain, Size: 7358 bytes --]

diff -r 3168aed4b01a contrib/web/php-admin/README
--- a/contrib/web/php-admin/README	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/README	Mon Mar 05 12:54:28 2012 +0100
@@ -22,8 +22,19 @@
    you need to create a group (eg. mlmmj) and add both users to it. The
    subscribers.d directory then needs to be writable by that group:
 
+     # addgroup mlmmj
+     # adduser wwwrun mlmmj
+     # adduser mailuser mlmmj
      # chgrp -R mlmmj /var/spool/mlmmj/mlmmj-test/subscribers.d/
      # chmod -R g+w /var/spool/mlmmj/mlmmj-test/subscribers.d/
+     # chmod g+s /var/spool/mlmmj/mlmmj-test/subscribers.d/
+
+   setgid flag is needed when the webserver calls mlmmj-sub and creates a file
+   under subscribers.d, to keep the mlmmj group.
+
+   If using the Exim mailserver, you should add initgroups = true in your
+   mlmmj_transport, otherwise it won't be able to write files having write
+   permission to mlmmj group.
 
 5) To enable access control on Apache you have to rename dot.htaccess to
    .htaccess and edit the path inside the file to point to a htpasswd file
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/index.php
--- a/contrib/web/php-admin/htdocs/index.php	Wed Feb 22 00:11:07 2012 +1100
+++ b/contrib/web/php-admin/htdocs/index.php	Mon Mar 05 12:54:28 2012 +0100
@@ -35,15 +35,15 @@
 
 $lists = "";
 
-$dir = opendir($topdir);
-while ($file = readdir($dir)) {
+# use scandir to have alphabetical order
+foreach (scandir($topdir) as $file) {
     if (!ereg("^\.",$file))
     {
-	$lists .= "<a href=\"edit.php?list=".urlencode($file)."\">".
-	    htmlentities($file)."</a><br />\n";
+	$lists .= "<p>".htmlentities($file)."<br/>\n";
+	$lists .= "<a href=\"edit.php?list=".urlencode($file)."\">Config</a> - <a href=\"subscribers.php?list=".urlencode($file)."\">Subscribers</a>\n";
+	$lists .= "</p>\n";
     }
 }
-closedir($dir); 
 
 $tpl->assign(array("LISTS" => $lists));
 
diff -r 3168aed4b01a contrib/web/php-admin/htdocs/subscribers.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/htdocs/subscribers.php	Mon Mar 05 12:54:28 2012 +0100
@@ -0,0 +1,114 @@
+<?php
+
+/* Copyright (C) 2012 Marc MAURICE <marc-mlmmj at pub dot positon dot org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+require(dirname(dirname(__FILE__))."/conf/config.php");
+require(dirname(__FILE__)."/class.rFastTemplate.php");
+
+$tpl = new rFastTemplate($templatedir);
+
+# get the list parameter and check that list exists
+$list = $_GET["list"];
+
+if(!isset($list))
+die("no list specified");
+
+if (dirname(realpath($topdir."/".$list)) != realpath($topdir))
+die("list outside topdir");
+
+if(!is_dir($topdir."/".$list))
+die("non-existent list");
+
+# this will be displayed on the top of the page
+$message = "";
+
+# subscribe some people if tosubscribe is set
+if (isset($_POST["tosubscribe"])) {
+	
+	foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
+		$email = trim($line);
+		if ($email != "") {
+			if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
+				$cmd = "/usr/bin/mlmmj-sub -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1";
+				unset($out);
+				exec($cmd, $out, $ret);
+				if ($ret !== 0) {
+					$message.= "* Subscribe error for $email\ncommand: $cmd\nreturn code: $ret\noutput: ".implode("\n", $out)."\n";
+				}
+			} else {
+				$message.= "* Email address not valid: $email\n";
+			}
+		}
+		
+	}
+
+# delete some people if delete is set
+} else if (isset($_POST["delete"])) {
+
+	$email = $_POST["email"];
+	if (! filter_var($email, FILTER_VALIDATE_EMAIL)) die("Email address not valid");
+	
+	$cmd = "/usr/bin/mlmmj-unsub -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1";
+	unset($out);
+	exec($cmd, $out, $ret);
+	if ($ret !== 0) {
+		$message.= "* Unsubscribe error.\ncommand: $cmd\nreturn code: $ret\noutput: ".implode("\n", $out)."\n";
+	}
+}
+
+$subscribers="";
+
+# get subscribers from mlmmj
+$cmd = "/usr/bin/mlmmj-list -L ".escapeshellarg("$topdir/$list")." 2>&1";
+unset($out);
+exec($cmd, $out, $ret);
+if ($ret !== 0) {
+	$message.= "* Error: Could not get subscribers list.\n";
+} else {
+
+	foreach ($out as $email) {
+		$email = trim($email);
+
+		$form = "<form action=\"subscribers.php?list=".htmlspecialchars($list)."\" method=\"post\" style=\"margin: 0; margin-left: 1em\">";
+		$form.= "<input type=\"hidden\" name=\"email\" value=\"".htmlspecialchars($email)."\" />";
+		$form.= "<input type=\"submit\" name=\"delete\" value=\"Remove\" />";
+		$form.= "</form>";
+
+		$subscribers.= "<tr><td>".htmlspecialchars($email)."</td><td>$form</td></tr>\n";
+	}
+
+	if ($subscribers === "") {
+		$subscribers = "<tr><td>This list is empty.</td></tr>\n";
+	}
+}
+
+# set template vars
+$tpl->define(array("main" => "subscribers.html"));
+
+$tpl->assign(array("LIST" => htmlspecialchars($list)));
+$tpl->assign(array("MESSAGE" => "<pre>".htmlspecialchars($message)."</pre>"));
+$tpl->assign(array("SUBS" => $subscribers));
+
+$tpl->parse("MAIN","main");
+$tpl->FastPrint("MAIN");
+
+?>
diff -r 3168aed4b01a contrib/web/php-admin/templates/subscribers.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/web/php-admin/templates/subscribers.html	Mon Mar 05 12:54:28 2012 +0100
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>mlmmj - {LIST} subscribers</title>
+<style type="text/css">
+#subscribers {
+	float: left;
+}
+
+#addsubscribers {
+        float: left;
+	margin-left: 2em;
+}
+#index {
+	clear: both;
+}
+</style>
+</head>
+<body>
+<h1>{LIST} subscribers</h1>
+
+{MESSAGE}
+
+<table id="subscribers">
+{SUBS}
+</table>
+
+<form method="post" action="subscribers.php?list={LIST}" id="addsubscribers">
+Add subscribers:<br/>
+<textarea name="tosubscribe" rows="5" cols="30">
+</textarea><br/>
+<input type="submit" name="submit" value="Add" />
+</form>
+
+<p id="index">
+<a href="index.php">Index</a>
+</p>
+</body>
+</html>
diff -r 3168aed4b01a src/subscriberfuncs.c
--- a/src/subscriberfuncs.c	Wed Feb 22 00:11:07 2012 +1100
+++ b/src/subscriberfuncs.c	Mon Mar 05 12:54:28 2012 +0100
@@ -132,6 +132,7 @@
 		subreadname = concatstr(2, subddirname, dp->d_name);
 		subread = open(subreadname, O_RDONLY);
 		if(subread < 0) {
+	                log_error(LOG_ARGS, "Could not open %s", subreadname);
 			myfree(subreadname);
 			continue;
 		}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (9 preceding siblings ...)
  2012-03-05 12:02 ` Marc MAURICE
@ 2012-03-06  8:45 ` Mads Martin Jørgensen
  2012-03-11 13:06 ` Ben Schmidt
  2012-03-11 13:46 ` Ben Schmidt
  12 siblings, 0 replies; 14+ messages in thread
From: Mads Martin Jørgensen @ 2012-03-06  8:45 UTC (permalink / raw)
  To: mlmmj

On 05/03/12 13.02, Marc MAURICE wrote:
> Ho I have on question : what is the main purpose of nomailers ?
> I understand that those people do not get any list mail.
> Is it to be able to post to a list without receiving mail with
> subonlypost ?

Yes.

Some people read the list and want to post from several addresses, but 
only want the list delivered in one of their mailboxes.

-- 
Mads Martin Joergensen, http://mmj.dk
"Why make things difficult, when it is possible to make them cryptic
  and totally illogical, with just a little bit more effort?"
                                  -- A. P. J.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (10 preceding siblings ...)
  2012-03-06  8:45 ` Mads Martin Jørgensen
@ 2012-03-11 13:06 ` Ben Schmidt
  2012-03-11 13:46 ` Ben Schmidt
  12 siblings, 0 replies; 14+ messages in thread
From: Ben Schmidt @ 2012-03-11 13:06 UTC (permalink / raw)
  To: mlmmj

Committed. Thank you, Marc.

If you're able to extend it one day to handle digesters and nomailers, just send 
the patch my way.

Smiles,

Ben.



On 5/03/12 11:02 PM, Marc MAURICE wrote:
> Hello Ben,
>
> Here is the new patch.
>
>> - You have added new files; could they have headers clarifying their
>> license, please?
> license added to subscribers.php
>> - /var/spool/mlmmj should not be hardcoded; you should use $topdir.
> done
>> - You need to unset($out) before calling exec(...,$out,...); see the PHP
>> documentation for exec().
> done
>> - Please don't ini_set display_errors to true; that could expose details
>> that the server administrator does not want to expose; admins should
>> have their PHP logging set up adequately to give them what they need,
>> or can change ini settings themselves if they need to.
> deleted
>> - Could you concatenate strings and use \n for linebreaks, please,
>> maintaining the indent in the PHP script, instead of having string
>> literals that span multiple lines?
> done in index.php
>> - Could you consider extending this slightly to allow subscription of
>> digesters and nomailers? (Update the README, too, to get permissions
>> set correctly on all relevant directories.) This could be a separate
>> patch, or omitted, but it would be nice.
> Yes, it would be better in a new patch.
> I will try to find some time to work on it next days.
>
> Ho I have on question : what is the main purpose of nomailers ?
> I understand that those people do not get any list mail.
> Is it to be able to post to a list without receiving mail with subonlypost ?
>
> I did not find anything about it in the doc.
>
> Thanks in advance,
>
> Marc
>
>
>
>>
>>
>>
>>
>> On 2/03/12 11:59 PM, Marc MAURICE wrote:
>>> Here is the new patch version.
>>>
>>> The email should be displayed, otherwise the user will have no clue about which
>>> email is wrong if his email list is very long.
>>>
>>> I put htmlspecialchars everywhere and errors are now enclosed in <pre> tags.
>>> no need for ln2br in <pre> tags no ?
>>>
>>> Marc
>>>
>>>
>>> Le 01/03/2012 16:07, Thomas Goirand a écrit :
>>>> On 03/01/2012 09:08 PM, Marc MAURICE wrote:
>>>>> +if (isset($_POST["tosubscribe"])) {
>>>>> +
>>>>> + foreach (preg_split('/\r\n|\n|\r/', $_POST["tosubscribe"]) as $line) {
>>>>> + $email = trim($line);
>>>>> + if ($email != "") {
>>>>> + if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
>>>>> + $cmd = "/usr/bin/mlmmj-sub -L '/var/spool/mlmmj/".escapeshellarg($list)."' -a
>>>>> '".escapeshellarg($email)."' 2>&1";
>>>>> + exec($cmd, $out, $ret);
>>>>> + if ($ret != 0) {
>>>>> + $message.= "Subscribe error for $email<!--cmd=$cmd out=".implode($out)."
>>>>> ret=$ret--> <br/>";
>>>>> + }
>>>>> + } else {
>>>>> + $message.= "Email address not valid: $email<br/>";
>>>> If $email isn't valid, then it's even more a reason not to display it
>>>> (eg: unless you want to shoot yourself in the foot with issues like
>>>> cross site scripting...).
>>>>
>>>> Also, I'm not sure what you are attempting with "displaying" the output
>>>> of the subscribing command in a HTML comment. Why not displaying it for
>>>> real, using htmlspecialchars() (which by the way, you didn't use, which
>>>> is dangerous) and ln2br() in a<pre> tag?
>>>>
>>>> Thomas
>>>>
>>>>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [mlmmj] Subscribers management in php-admin
  2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
                   ` (11 preceding siblings ...)
  2012-03-11 13:06 ` Ben Schmidt
@ 2012-03-11 13:46 ` Ben Schmidt
  12 siblings, 0 replies; 14+ messages in thread
From: Ben Schmidt @ 2012-03-11 13:46 UTC (permalink / raw)
  To: mlmmj

On 6/03/12 7:45 PM, Mads Martin Jørgensen wrote:
> On 05/03/12 13.02, Marc MAURICE wrote:
>> Ho I have on question : what is the main purpose of nomailers ?
>> I understand that those people do not get any list mail.
>> Is it to be able to post to a list without receiving mail with
>> subonlypost ?
>
> Yes.
>
> Some people read the list and want to post from several addresses, but only want
> the list delivered in one of their mailboxes.

And it can also be useful just to 'turn off' the list when you're away
on holidays instead of needing to fully unsubscribe and subscribe again
(and confirm it each time or, in the case of a closed list, bother an
administrator).

Ben.





^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-03-11 13:46 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-27 21:50 [mlmmj] Subscribers management in php-admin Marc MAURICE
2012-02-28  9:25 ` Thomas Goirand
2012-02-28  9:47 ` Marc MAURICE
2012-02-28 14:29 ` Ben Schmidt
2012-02-29  3:09 ` Thomas Goirand
2012-02-29  3:57 ` Ben Schmidt
2012-03-01 13:08 ` Marc MAURICE
2012-03-01 15:07 ` Thomas Goirand
2012-03-02 12:59 ` Marc MAURICE
2012-03-04 14:05 ` Ben Schmidt
2012-03-05 12:02 ` Marc MAURICE
2012-03-06  8:45 ` Mads Martin Jørgensen
2012-03-11 13:06 ` Ben Schmidt
2012-03-11 13:46 ` Ben Schmidt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.