Commit 75081528 authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

Fixup the mailman support so that instead of using @emulab.net

addresses in the list, use real email addresses. Why? Well, cause I'm
a dope.  Oh, the real reason is that people cannot post to the lists
if we use their @emulab.net addresses cause we close the lists (to
avoid spammers). I did it this way originally cause it was easier;
there is a lot more bookkeeping to do if using real addresses, and I
never consider problem of not being able to post.
parent 4d7dd46b
......@@ -43,6 +43,7 @@ my $WITHSFS = @SFSSUPPORT@;
my $WIKISUPPORT = @WIKISUPPORT@;
my $BUGDBSUPPORT= @BUGDBSUPPORT@;
my $CHATSUPPORT = @CHATSUPPORT@;
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
my $PROTOUSER = 'elabman';
my $SAMBANODE = "fs"; # DNS makes this do the right thing in E-in-E.
......@@ -56,7 +57,6 @@ my $USERDEL = "/usr/sbin/pw userdel";
my $USERMOD = "/usr/sbin/pw usermod";
my $CHPASS = "/usr/bin/chpass";
my $SFSKEYGEN = "/usr/local/bin/sfskey gen";
my $SETGROUPS = "$TB/sbin/setgroups";
my $GENELISTS = "$TB/sbin/genelists";
my $MKUSERCERT = "$TB/sbin/mkusercert";
my $SFSUPDATE = "$TB/sbin/sfskey_update";
......@@ -68,6 +68,9 @@ my $ADDBUGDBUSER= "$TB/sbin/addbugdbuser";
my $DELBUGDBUSER= "$TB/sbin/delbugdbuser";
my $ADDCHATUSER = "$TB/sbin/addjabberuser";
my $DELCHATUSER = "$TB/sbin/deljabberuser";
my $MMMODIFYUSER= "$TB/sbin/mmmodifymember";
my $ADDMMUSER = "$TB/sbin/addmmuser";
my $DELMMUSER = "$TB/sbin/delmmuser";
my $NOLOGIN = "/sbin/nologin";
my $SSH = "$TB/bin/sshtb";
my $SAVEUID = $UID;
......@@ -371,6 +374,10 @@ sub AddUser()
system("$ADDCHATUSER $user")
if ($CHATSUPPORT && !$batch && $user ne $PROTOUSER);
# And the mailman lists if enabled.
system("$ADDMMUSER $user")
if ($MAILMANSUPPORT);
# Generate the SSL cert for the user.
system("$MKUSERCERT $user");
......@@ -455,6 +462,10 @@ sub DelUser()
system("$DELCHATUSER $user")
if ($CHATSUPPORT);
# And the mailman lists if enabled.
system("$DELMMUSER $user")
if ($MAILMANSUPPORT);
$EUID = 0;
$sfsupdate = 1;
......@@ -603,6 +614,10 @@ sub UpdateUser(;$)
$UID = $SAVEUID;
$EUID = $UID;
# Update elists in case email changed.
system("$MMMODIFYUSER $user")
if ($MAILMANSUPPORT && !$batch);
# Update elists in case email changed.
system("$GENELISTS -m -u $user");
$EUID = 0;
......
......@@ -12,7 +12,8 @@ SUBDIR = collab/mailman
include $(OBJDIR)/Makeconf
SBIN_SCRIPTS = addmmlist delmmlist setmmlistmembers mmsetup \
setmmpasswd mmlistmembership
setmmpasswd mmlistmembership mmmodifymember \
addmmuser delmmuser
LIBEXEC_SCRIPTS = webaddmmlist webdelmmlist websetmmpasswd mmxlogin \
webmmlistmembership
CTRL_LIBEXEC_SCRIPTS = genaliases
......@@ -38,6 +39,10 @@ install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_SCRIPTS)) \
boss-install: install
post-install:
chown root $(INSTALL_SBINDIR)/addmmuser
chmod u+s $(INSTALL_SBINDIR)/addmmuser
chown root $(INSTALL_SBINDIR)/delmmuser
chmod u+s $(INSTALL_SBINDIR)/delmmuser
chown root $(INSTALL_SBINDIR)/addmmlist
chmod u+s $(INSTALL_SBINDIR)/addmmlist
chown root $(INSTALL_SBINDIR)/delmmlist
......@@ -50,6 +55,8 @@ post-install:
chmod u+s $(INSTALL_SBINDIR)/mmlistmembership
chown root $(INSTALL_LIBEXECDIR)/mmxlogin
chmod u+s $(INSTALL_LIBEXECDIR)/mmxlogin
chown root $(INSTALL_SBINDIR)/mmmodifymember
chmod u+s $(INSTALL_SBINDIR)/mmmodifymember
#
# Control node installation (okay, plastic)
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Errno qw(EEXIST);
#
# Add a mailman user.
#
sub usage()
{
print STDOUT "Usage: addmmuser <uid>\n";
exit(-1);
}
my $optlist = "d";
my $debug = 0;
my $dbuid;
my $target_uid;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $OURDOMAIN = "@OURDOMAIN@";
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
my $SSH = "$TB/bin/sshtb";
my $MMPROXY = "$TB/sbin/mailmanproxy";
# Protos
sub fatal($);
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be setuid! Maybe its a development version?\n");
}
#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
die("*** $0:\n".
" Please do not run this as root! Its already setuid!\n");
}
#
# If no mailman support, just exit.
#
if (! $MAILMANSUPPORT) {
print "MailMan support is not enabled. Exit ...\n";
exit(0);
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
usage()
if (@ARGV != 1);
$target_uid = $ARGV[0];
#
# Untaint args.
#
if ($target_uid =~ /^([-\w]+)$/) {
$target_uid= $1;
}
else {
die("Bad data in uid: $target_uid");
}
my $query_result =
DBQueryFatal("select usr_email, mailman_password, usr_name ".
"from users where uid='$target_uid'");
fatal("No such user in DB: $target_uid!")
if (!$query_result->numrows);
my ($email, $password, $fullname) = $query_result->fetchrow_array();
#
# Note that since we are sending cleartext passwords over, pipe the info
# into its STDIN so that the passwords are not visible in a ps listing.
#
# For ssh.
#
$UID = $EUID;
if ($CONTROL ne $BOSSNODE) {
my $optarg = ($debug ? "-d" : "");
print "Adding user $target_uid to Mailman DB on $CONTROL.\n";
# Must serialize some of the mailman stuff. Be sure to use the same token!
TBScriptLock("mailman_update") == 0 or
fatal("Could not get the lock!");
system("echo \"$password \'$fullname\'\" | ".
"$SSH -host $CONTROL $MMPROXY $optarg adduser $target_uid $email");
my $status = $?;
TBScriptUnlock();
$? = $status;
if ($?) {
if ($? >> 8 == EEXIST()) {
print "addmmuser: $target_uid already exists in the mailman DB\n"
if ($debug);
exit(0);
}
fatal("$MMPROXY failed on $CONTROL!");
}
}
exit(0);
sub fatal($)
{
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Errno qw(EEXIST);
#
# Add a mailman user.
#
sub usage()
{
print STDOUT "Usage: delmmuser <uid>\n";
exit(-1);
}
my $optlist = "d";
my $debug = 0;
my $dbuid;
my $target_uid;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $OURDOMAIN = "@OURDOMAIN@";
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
my $SSH = "$TB/bin/sshtb";
my $MMPROXY = "$TB/sbin/mailmanproxy";
# Protos
sub fatal($);
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be setuid! Maybe its a development version?\n");
}
#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
die("*** $0:\n".
" Please do not run this as root! Its already setuid!\n");
}
#
# If no mailman support, just exit.
#
if (! $MAILMANSUPPORT) {
print "MailMan support is not enabled. Exit ...\n";
exit(0);
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
usage()
if (@ARGV != 1);
$target_uid = $ARGV[0];
#
# Untaint args.
#
if ($target_uid =~ /^([-\w]+)$/) {
$target_uid= $1;
}
else {
die("Bad data in uid: $target_uid");
}
my $query_result =
DBQueryFatal("select usr_email, mailman_password, usr_name ".
"from users where uid='$target_uid'");
fatal("No such user in DB: $target_uid!")
if (!$query_result->numrows);
my ($email, $password, $fullname) = $query_result->fetchrow_array();
#
# Note that since we are sending cleartext passwords over, pipe the info
# into its STDIN so that the passwords are not visible in a ps listing.
#
# For ssh.
#
$UID = $EUID;
if ($CONTROL ne $BOSSNODE) {
my $optarg = ($debug ? "-d" : "");
print "Removing user $target_uid from Mailman DB on $CONTROL.\n";
# Must serialize some of the mailman stuff. Be sure to use the same token!
TBScriptLock("mailman_update") == 0 or
fatal("Could not get the lock!");
system("$SSH -host $CONTROL $MMPROXY $optarg deluser $target_uid $email");
my $status = $?;
TBScriptUnlock();
$? = $status;
if ($?) {
fatal("$MMPROXY failed on $CONTROL!");
}
}
exit(0);
sub fatal($)
{
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
......@@ -7,7 +7,7 @@
use English;
use Getopt::Std;
use Errno qw(EEXIST);
#
# A wrapper for messing with Mailman from boss.
#
......@@ -15,7 +15,7 @@ sub usage()
{
print "Usage: mailmanproxy addlist <listname> <listtype> or\n";
print " mailmanproxy setlistmembers <listname> or\n";
print " mailmanproxy modifymember <email> or\n";
print " mailmanproxy modifymember <uid> <email> or\n";
print " mailmanproxy setadminpassword <listname>\n";
print " mailmanproxy dellist <listname>\n";
exit(-1);
......@@ -34,6 +34,12 @@ my $MAILMANDIR = "/usr/local/mailman";
my $MMBINDIR = "$MAILMANDIR/bin";
my $MMLISTDIR = "$MAILMANDIR/lists";
my $GENALIASES = "$TB/libexec/mailman/genaliases";
my $IDHASH = "/var/db/emulabid2email";
my $EMAILHASH = "/var/db/email2emulabid";
# Locals.
my %IDhash;
my %EMAILhash;
#
# Turn off line buffering on output
......@@ -92,6 +98,15 @@ if (! @ARGV) {
usage();
}
#
# These will just start out as empty hashes so everything is added.
#
dbmopen(%IDhash, $IDHASH, 0660) or
fatal("Cannot open $IDHASH: $!");
dbmopen(%EMAILhash, $EMAILHASH, 0660) or
fatal("Cannot open $EMAILHASH: $!");
#
# Before we continue, flip to mailman user/group.
#
......@@ -135,15 +150,184 @@ elsif ($action eq "xlogin") {
elsif ($action eq "membership") {
exit(ListMembership(@ARGV));
}
elsif ($action eq "adduser") {
exit(AddUser(@ARGV));
}
elsif ($action eq "deluser") {
exit(DelUser(@ARGV));
}
elsif ($action eq "reconfig") {
exit(AddList(1, @ARGV));
}
else {
die("*** $0:\n".
" Do not know what to do with '$action'!\n");
fatal("Do not know what to do with '$action'!\n");
}
exit(0);
#
# Map between emulab id and user email address in the DB. Return 0 on
# success, -1 is there is no mapping.
#
sub EmulabID2Email($$)
{
my ($uid, $pemail) = @_;
return -1
if (!defined($IDhash{$uid}));
# Sanity check
if (!defined($EMAILhash{$IDhash{$uid}}) ||
$EMAILhash{$IDhash{$uid}} ne $uid) {
fatal("Inconsistent mapping for $uid!");
}
if ($debug) {
print "EmulabID2Email: $uid " . $IDhash{$uid} . "\n";
}
$$pemail = $IDhash{$uid};
return 0;
}
sub Email2EmulabID($$)
{
my ($email, $puid) = @_;
return -1
if (!defined($EMAILhash{$email}));
# Sanity check
if (!defined($IDhash{$EMAILhash{$email}}) ||
$IDhash{$EMAILhash{$email}} ne $email) {
fatal("Inconsistent mapping for $email!");
}
if ($debug) {
print "Email2EmulabID: $email " . $EMAILhash{$email} . "\n";
}
$$puid = $EMAILhash{$email};
return 0;
}
#
# Store the mapping in the dbm files.
#
sub StoreMapping($$)
{
my ($ID, $email) = @_;
$IDhash{$ID} = $email;
$EMAILhash{$email} = $ID;
return 0;
}
# Delete a mapping.
sub DeleteMapping($$)
{
my ($ID, $email) = @_;
delete($IDhash{$ID});
delete($EMAILhash{$email});
return 0;
}
#
# Add user.
#
sub AddUser(@)
{
my ($uid, $email) = @_;
usage()
if (@_ != 2);
# See if already exists.
my $oldemail;
my $olduid;
# Map to EMAIL.
if (EmulabID2Email($uid, \$oldemail) == 0) {
fatal("AddUser: $uid already exists with another email: $oldemail!")
if ($email ne $oldemail);
return EEXIST();
}
# Map to UID.
if (Email2EmulabID($email, \$olduid) == 0) {
fatal("AddUser: $email already exists with another uid: $olduid!")
if ($uid ne $olduid);
return EEXIST();
}
StoreMapping($uid, $email);
return 0;
}
#
# Del user.
#
sub DelUser(@)
{
usage()
if (@_ != 2);
my ($uid, $email) = @_;
# See if already exists.
my $oldemail;
# Map to EMAIL.
if (EmulabID2Email($uid, \$oldemail) < 0) {
print "DelUser: No such user $uid in the mailman database!\n";
return 0;
}
fatal("DelUser: User $uid is in the DB with another email: $oldemail!")
if ($email ne $oldemail);
#
# If the user is still in any email lists owned by tbops, its an error.
#
my @listnames = ();
#
# Very convenient script provided by mailman ...
#
# The script we call expects regex, and embedded + signs mess things up.
#
my $emailcopy = $email;
$emailcopy =~ s/([^\\])([\+])/$1\\$2/g;
open(NAMES, "$MMBINDIR/find_member '$emailcopy' |") or
fatal("DelUser: Could not start up find_member!");
while (<NAMES>) {
if ($_ =~ /^\s*([^\s]*)$/) {
push(@listnames, $1);
}
}
close(NAMES) or
fatal("DelUser: Error running find_member script!");
foreach my $listname (@listnames) {
#
# Another convenient script provided by mailman ...
#
open(OWNER, "$MMBINDIR/list_owners '$listname' |") or