Commit 113bacef authored by Leigh B. Stoller's avatar Leigh B. Stoller

Move all modification of the group_membership table to the backend,

into a single new script call modgroups. Usage:

 	modgroups [-a pid:gid:trust[,pid:gid:trust]...]
                    [-m pid:gid:trust[,pid:gid:trust]...]
                    [-r pid:gid[,pid:gid]...] user

So, -a to add groups, -r to remove groups, and -m to modify the trust
value for a member of a group.

The reason for doing this is that previously, we had no idea in the
backend what group changes actually happened; we just knew what the
current groups are. This make it hard to add and remove users from
mailing lists, chat server buddy lists, etc. This is cleaner ...
parent 8520c6fb
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
#
# Modify groups (add and subtract in DB) for a user, and then call
# other scripts that need to do something about it.
#
# Note that this script does not create accounts or groups. That should
# already have been done with other scripts.
#
sub usage()
{
print STDOUT
"Usage: modgroups [-a pid:gid:trust[,pid:gid:trust]...] ".
"[-m pid:gid:trust[,pid:gid:trust]...] ".
"[-r pid:gid[,pid:gid]...] user\n";
exit(-1);
}
my $optlist = "dr:a:m:";
my $debug = 0;
my $user;
my @addlist = ();
my @modlist = (); # Just changing the trust value ...
my @remlist = ();
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $CONTROL = "@USERNODE@";
my $BOSSNODE = "@BOSSNODE@";
my $WIKISUPPORT = @WIKISUPPORT@;
my $BUGDBSUPPORT = @BUGDBSUPPORT@;
my $CHATSUPPORT = @CHATSUPPORT@;
my $MODBUDDIES = "$TB/sbin/modjabberbuddies";
my $SETGROUPS = "$TB/sbin/setgroups";
my $SSH = "$TB/bin/sshtb";
my $SAVEUID = $UID;
# Locals
my $dbuid;
#
# 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 libaudit;
use libdb;
use libtestbed;
# Protos
sub fatal($);
#
# 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!\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;
}
if (defined($options{"a"})) {
my @tokens = split(",", $options{"a"});
foreach my $token (@tokens) {
#
# Untaint,
#
if ($token =~ /^([-\w]+):([-\w]+):([-\w]+)$/) {
push(@addlist, "$1:$2:$3");
}
else {
die("Bad data in token: $token.");
}
}
}
if (defined($options{"m"})) {
my @tokens = split(",", $options{"m"});
foreach my $token (@tokens) {
#
# Untaint,
#
if ($token =~ /^([-\w]+):([-\w]+):([-\w]+)$/) {
push(@modlist, "$1:$2:$3");
}
else {
die("Bad data in token: $token.");
}
}
}
if (defined($options{"r"})) {
my @tokens = split(",", $options{"r"});
foreach my $token (@tokens) {
#
# Untaint,
#
if ($token =~ /^([-\w]+):([-\w]+)$/) {
push(@remlist, "$1:$2");
}
else {
die("Bad data in token: $token.");
}
}
}
usage()
if (@ARGV != 1);
$user = $ARGV[0];
# Untaint the user.
if ($user =~ /^([\w]+)$/) {
$user = $1;
}
else {
die("Bad user name: $user.");
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Permission checks. Do this later.
#
#
# This script is always audited. Mail is sent automatically upon exit.
#
if (AuditStart(0)) {
#
# Parent exits normally
#
exit(0);
}
#
# Add groups. Do any necessary callouts.
#
foreach my $token (@addlist) {
my ($pid,$gid,$trust) = split(":", $token);
#
# Look to see if there is already an entry; this happens as the result
# of either a join request or a new project request. The row is inserted
# but with a trust value of "none". We probably want a pending table ...
#
my $query_result =
DBQueryFatal("select trust from group_membership ".
"where pid='$pid' and gid='$gid' and uid='$user'");
if ($query_result->num_rows) {
#
# Sanity check; better be trust=none.
#
my ($curtrust) = $query_result->fetchrow_array();
fatal("Group membership table problem; ".
"$user,$pid,$gid,$trust,$curtrust\n")
if ($curtrust ne "none");
DBQueryFatal("update group_membership set ".
" trust='$trust', ".
" date_approved=now() ".
"where pid='$pid' and gid='$gid' and uid='$user'");
}
else {
DBQueryFatal("insert into group_membership set ".
" uid='$user', ".
" pid='$pid', ".
" gid='$gid', ".
" trust='$trust', ".
" date_applied=now(), ".
" date_approved=now()");
}
#
# Tell chat subsystem to change groups ...
#
if ($CHATSUPPORT) {
system("$MODBUDDIES -a $pid:$gid $user") == 0 or
fatal("$MODBUDDIES '-a $pid:$gid $user' failed!");
}
}
#
# Update groups. Do any necessary callouts.
#
foreach my $token (@modlist) {
my ($pid,$gid,$trust) = split(":", $token);
DBQueryFatal("update group_membership set trust='$trust' ".
"where pid='$pid' and gid='$gid' and uid='$user'");
}
#
# Remove groups. Do any necessary callouts.
#
foreach my $token (@remlist) {
my ($pid,$gid) = split(":", $token);
my @delgroups = ();
#
# Special case; if pid==gid then delete from the project entirely.
# However, we want to get a list of the groups about to be deleted
# so we know what to hand off to the callouts.
#
if ($pid eq $gid) {
my $query_result =
DBQueryFatal("select gid from group_membership ".
"where uid='$user' and pid='$pid'");
while (my ($gid) = $query_result->fetchrow_array()) {
push(@delgroups, $gid);
}
}
else {
@delgroups = ($gid);
}
DBQueryFatal("delete from group_membership ".
"where pid='$pid' and ".
(($pid ne $gid) ? "gid='$gid' and " : " ") .
" uid='$user'");
#
# Tell chat subsystem to change groups ...
#
if ($CHATSUPPORT) {
my $chatargs = "";
foreach my $group (@delgroups) {
$chatargs = "$chatargs $pid:$group";
}
system("$MODBUDDIES -r $chatargs $user") == 0 or
fatal("$MODBUDDIES '-r $chatargs $user' failed!");
}
}
#
# Finally, call setgroups to do the rest.
#
system("$SETGROUPS $user") == 0 or
fatal("$SETGROUPS $user failed!");
exit(0);
sub fatal($) {
my($mesg) = $_[0];
die("*** $0:\n".
" $mesg\n");
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment