Commit cc1c4e54 authored by Leigh Stoller's avatar Leigh Stoller

Add stuff to update the SFS keys on the fileserver after someone uses

the web page to add/delete a key! Nodes were getting updated, but
the SFS server was not cause there was no program to fire the new keys
over there.

The operation is currently simple. sfskey_update on boss constructs a
new sfs_users file. Then it runs sfskey_update.proxy on ops (vis ssh
of course), and gives it the new file via stdin. The proxy creates the
.pub version from that file, and then moves the two new files into
place in /etc/sfs. I employ the same locking stuff that Rob did in
exports_setup and named_setup to prevent multiple updates from
stacking up. Not likely, but might as well. Also note that the entire
file is regenerated. When we get 5000 users this might have to change
a little bit!

Also changed mkacct slightly. Instead of doing a "sfskey register" on
ops after generating the new key, just add it to the DB. Then fire off
an sfskey_update to push the new keys over. Also add a -f flag to
mkacct for use from the web page to indicate that the user has changed
his SFS keys. Note that mkacct should probably take a series of flags
since we have it as a wrapper for several things. Or maybe split all
this stuff up.
parent eeb08108
......@@ -1279,12 +1279,13 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/savelogs tbsetup/setgroups tbsetup/websetgroups \
tbsetup/rmgroup tbsetup/webrmgroup tbsetup/mkexpdir \
tbsetup/webnodecontrol tbsetup/node_control \
tbsetup/webmkgroup tbsetup/mkgroup \
tbsetup/webmkgroup tbsetup/mkgroup tbsetup/eventsys_start \
tbsetup/webmkacct tbsetup/mkacct tbsetup/eventsys_control \
tbsetup/webmkproj tbsetup/mkproj tbsetup/libtestbed.pm \
tbsetup/portstats tbsetup/vnode_setup tbsetup/staticroutes \
tbsetup/console_setup.proxy tbsetup/exports_setup.proxy \
tbsetup/checkports tbsetup/webidlecheck tbsetup/webnodereboot \
tbsetup/sfskey_update tbsetup/sfskey_update.proxy \
tip/GNUmakefile \
tmcd/GNUmakefile tmcd/freebsd/GNUmakefile tmcd/linux/GNUmakefile \
tmcd/ron/GNUmakefile \
......@@ -1293,6 +1294,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
utils/GNUmakefile utils/vlandiff utils/vlansync utils/delay_config \
utils/sshtb utils/create_image utils/node_admin utils/webcreateimage \
utils/firstuser utils/export_tables\
utils/addpubkey utils/webaddpubkey utils/cvsupd.pl \
www/GNUmakefile www/defs.php3 www/dbdefs.php3 \
vis/GNUmakefile vis/vistopology vis/webvistopology vis/top2gif \
vis/dbvistopology vis/dbtopper \
......
......@@ -336,12 +336,13 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/savelogs tbsetup/setgroups tbsetup/websetgroups \
tbsetup/rmgroup tbsetup/webrmgroup tbsetup/mkexpdir \
tbsetup/webnodecontrol tbsetup/node_control \
tbsetup/webmkgroup tbsetup/mkgroup \
tbsetup/webmkgroup tbsetup/mkgroup tbsetup/eventsys_start \
tbsetup/webmkacct tbsetup/mkacct tbsetup/eventsys_control \
tbsetup/webmkproj tbsetup/mkproj tbsetup/libtestbed.pm \
tbsetup/portstats tbsetup/vnode_setup tbsetup/staticroutes \
tbsetup/console_setup.proxy tbsetup/exports_setup.proxy \
tbsetup/checkports tbsetup/webidlecheck tbsetup/webnodereboot \
tbsetup/sfskey_update tbsetup/sfskey_update.proxy \
tip/GNUmakefile \
tmcd/GNUmakefile tmcd/freebsd/GNUmakefile tmcd/linux/GNUmakefile \
tmcd/ron/GNUmakefile \
......@@ -349,7 +350,8 @@ outfiles="$outfiles Makeconf GNUmakefile \
tmcd/tmcd.restart \
utils/GNUmakefile utils/vlandiff utils/vlansync utils/delay_config \
utils/sshtb utils/create_image utils/node_admin utils/webcreateimage \
utils/firstuser utils/export_tables\
utils/firstuser utils/export_tables \
utils/addpubkey utils/webaddpubkey utils/cvsupd.pl \
www/GNUmakefile www/defs.php3 www/dbdefs.php3 \
vis/GNUmakefile vis/vistopology vis/webvistopology vis/top2gif \
vis/dbvistopology vis/dbtopper \
......
......@@ -27,7 +27,8 @@ SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
batch_daemon exports_setup reload_daemon sched_reserve \
console_reset db2ns bwconfig frisbeelauncher \
rmgroup mkgroup mkacct setgroups mkproj \
exports_setup.proxy vnode_setup eventsys_start
exports_setup.proxy vnode_setup eventsys_start \
sfskey_update sfskey_update.proxy
LIBEXEC_STUFF = rmproj rmacct-ctrl wanlinksolve wanlinkinfo \
os_setup mkexpdir console_setup webnscheck webreport \
......@@ -104,6 +105,8 @@ post-install:
chmod u+s $(INSTALL_SBINDIR)/named_setup
chown root $(INSTALL_SBINDIR)/exports_setup
chmod u+s $(INSTALL_SBINDIR)/exports_setup
chown root $(INSTALL_SBINDIR)/sfskey_update
chmod u+s $(INSTALL_SBINDIR)/sfskey_update
chown root $(INSTALL_SBINDIR)/setgroups
chmod u+s $(INSTALL_SBINDIR)/setgroups
chown root $(INSTALL_LIBEXECDIR)/console_setup
......@@ -131,6 +134,7 @@ LINKS= cd $(INSTALL_BINDIR) && \
endif
control-install: $(addprefix $(INSTALL_SBINDIR)/, console_setup.proxy) \
$(addprefix $(INSTALL_SBINDIR)/, exports_setup.proxy) \
$(addprefix $(INSTALL_SBINDIR)/, sfskey_update.proxy) \
$(addprefix $(INSTALL_LIBDIR)/, libtestbed.pm)
$(LINKS)
......
......@@ -19,10 +19,10 @@ use Getopt::Std;
#
sub usage()
{
print STDOUT "Usage: mkacct [-a] <name>\n";
print STDOUT "Usage: mkacct [-a] [-f] <name>\n";
exit(-1);
}
my $optlist = "a";
my $optlist = "af";
#
# Configure variables
......@@ -47,8 +47,10 @@ my $SFSKEYGEN = "/usr/local/bin/sfskey gen";
my $SFSKEYREG = "/usr/local/bin/sfskey register";
my $SETGROUPS = "$TB/sbin/setgroups";
my $GENELISTS = "$TB/sbin/genelists";
my $SFSUPDATE = "$TB/sbin/sfskey_update";
my $auditmode = 0;
my $sfschange = 0;
my $logname;
my $user;
my @db_row;
......@@ -105,6 +107,9 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"a"})) {
$auditmode = 1;
}
if (defined($options{"f"})) {
$sfschange = 1;
}
if (@ARGV != 1) {
usage();
}
......@@ -369,6 +374,18 @@ while (my %row = $query_result->fetchhash()) {
TBNodeUpdateAccountsByPid($pid);
}
#
# If an SFS change was requested (or a new user), then must update.
#
if ($WITHSFS && $sfschange) {
#
# Note that this command must be run when EUID==UID==0 because its
# a setuid PERL script.
#
system($SFSUPDATE) == 0
or fatal("$SFSUPDATE failed!");
}
if ($auditmode) {
AUDIT("Account Create Completed!\n", 0);
unlink($logname);
......@@ -430,20 +447,16 @@ sub FirstTime()
"$user\@ops.emulab.net $SFSDIR/identity'")) {
fatal("Failure in sfskey gen: $!");
}
$sfschange = 1;
chown($user_number, $default_groupgid, "$SFSDIR/identity") or
fatal("Could not chown $SFSDIR/identity: $!");
chmod(0600, "$SFSDIR/identity") or
fatal("Could not chmod $SFSDIR/identity: $!");
print "Registering sfs key\n";
if (system("$SSH -host $control_node '$SFSKEYREG -Su ".
"$user $SFSDIR/identity'")) {
fatal("Failure in sfskey register: $!");
}
#
# Grab a copy for the DB.
# Grab a copy for the DB. Causes an SFS update key to run so
# that key is inserted into the files.
#
my $ident = `cat $SFSDIR/identity`;
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Fcntl ':flock';
#
# Create new sfs_users file and fire it off to the SFS server to
# install via the proxy perl script.
#
# This script always does the right thing, so it does not matter who calls it.
#
# usage: sfskey_update
#
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TESTMODE = @TESTMODE@;
my $FSNODE = "@FSNODE@";
# Note no -n option. We redirect stdin from the new exports file below.
my $SSH = "$TB/bin/sshtb -l root -host $FSNODE";
my $PROG = "/usr/testbed/sbin/sfskey_update.proxy";
my $keyfile = "/var/tmp/sfs_users";
my $lockfile = "/var/tmp/testbed_sfsusers_lockfile";
my $dbg = 1;
my @row;
#
# We do not want to run this script unless its the real version.
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be root! Maybe its a development version?\n");
}
# XXX Hacky!
if (0 && $TB ne "/usr/testbed") {
print STDERR "*** $0:\n".
" Wrong version. Maybe its a development version?\n";
#
# Let experiment continue setting up.
#
exit(0);
}
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/sbin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
#
# We need to serialize this script to avoid a trashed file. Use
# a dummy file in /var/tmp, opened for writing and flock'ed.
#
if (!$TESTMODE) {
open(LOCK, ">>$lockfile") || fatal("Couldn't open $lockfile\n");
$count = 0;
if (flock(LOCK, LOCK_EX|LOCK_NB) == 0) {
#
# If we don't get it the first time, we wait for:
# 1) The lock to become free, in which case we do our thing
# 2) The time on the lock to change, in which case we wait for
# that process to finish
#
my $oldlocktime = (stat(LOCK))[9];
my $gotlock = 0;
while (1) {
print "Another sfskey update running, waiting for it to finish\n";
if (flock(LOCK, LOCK_EX|LOCK_NB) != 0) {
# OK, got the lock, we can do what we're supposed to
$gotlock = 1;
last;
}
$locktime = (stat(LOCK))[9];
if ($locktime != $oldlocktime) {
$oldlocktime = $locktime;
last;
}
if ($count++ > 20) {
fatal("Could not get the lock after a long time!\n");
}
sleep(1);
}
$count = 0;
#
# If we didn't get the lock, wait for the processes that did to finish
#
if (!$gotlock) {
while (1) {
if ((stat(LOCK))[9] != $oldlocktime) {
exit(0);
}
if (flock(LOCK, LOCK_EX|LOCK_NB) != 0) {
close(LOCK);
exit(0);
}
if ($count++ > 20) {
fatal("Process with the lock did not finish ".
"after a long time!\n");
}
sleep(1);
}
}
}
}
#
# Perl-style touch(1)
#
my $now = time;
utime $now, $now, $lockfile;
#
# Create new keyfile.
#
if (!$TESTMODE) {
open(KEYS, ">$keyfile")
or fatal("Could not open $keyfile");
}
else {
open(KEYS, ">/dev/null")
or fatal("Could not open /dev/null");
}
#
# Grab all the keys from the DB and stick into the file.
#
my $query_result =
DBQueryFatal("select pubkey from user_sfskeys");
while (my ($pubkey) = $query_result->fetchrow_array()) {
print KEYS "$pubkey\n";
}
close(KEYS);
#
# Fire the new tail file over to the fileserver to finish. We cat the file
# right into it.
#
if (!$TESTMODE) {
print "Updating sfs keys on $FSNODE\n";
#
# Real root for ssh.
#
$UID = 0;
system("$SSH $PROG < $keyfile") == 0 or
fatal("Failed: $SSH $PROG < $keyfile: $?");
#
# Close the lock file. Exiting releases it, but might as well.
#
close(LOCK);
}
exit(0);
sub fatal {
local($msg) = $_[0];
SENDMAIL($TBOPS, "SFS key update failed", $msg);
die("*** $0:\n".
" $msg\n");
}
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2002 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
#
# Manage the sfs_users files remotely from boss. The keys to change are
# passed in via stdin. Must use locking of course.
#
sub usage()
{
print "Usage: sfskey_update.proxy\n";
exit(-1);
}
my $optlist = "";
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
#
# Locals
#
my $tmpkey = "/var/tmp/sfs_users";
my $tmppub = "/var/tmp/sfs_users.pub";
my $realkey = "/etc/sfs/sfs_users";
my $realpub = "/etc/sfs/sfs_users.pub";
my @newkeys = ();
# un-taint path
$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Turn off line buffering on output
$| = 1;
#
# We don't want to run this script unless its the real version.
#
if ($UID != 0) {
die("*** $0:\n".
" Must be root! Maybe the wrong version?\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 (@ARGV != 0) {
usage();
}
#
# Take in our input and stash it. First field is the unique key.
#
while (<STDIN>) {
chomp();
push(@newkeys, $_);
}
if (! @newkeys) {
print STDERR "No keys! Exiting ...\n";
exit(0);
}
#
# Create two temp files, one for the key file and one for the pub file.
#
system("rm -f $tmpkey $tmppub") == 0
or fatal("Could not remove old tmp files");
my $oldmask = umask(0077);
open(OUTKEY, "> $tmpkey")
or fatal("Could not open $tmpkey: $!");
umask(0022);
open(OUTPUB, "> $tmppub")
or fatal("Could not open $tmppub: $!");
umask($oldmask);
print OUTKEY "#\n";
print OUTKEY "# This file is autogenerated from boss. DO NOT EDIT!\n";
print OUTKEY "#\n";
print OUTPUB "#\n";
print OUTPUB "# This file is autogenerated from boss. DO NOT EDIT!\n";
print OUTPUB "#\n";
#
# Parse each input line, separating the various sections (by colon).
#
foreach my $key ( @newkeys ) {
if (! ($key =~ /^(.*):(.*):(.*):(.*):(.*)$/)) {
print STDERR "Bad key line: $key\n";
next;
}
print OUTKEY "$1:$2:$3:$4:$5\n";
print OUTPUB "$1:$2:$3::\n";
}
close(OUTKEY)
or fatal("Error closing $tmpkey: $!");
close(OUTPUB)
or fatal("Error closing $tmppub: $!");
#
# Back up old ones and move new ones into place.
#
system("cp -pf $realkey ${realkey}.old") == 0
or fatal("Could not backup $realkey");
system("cp -pf $realpub ${realpub}.old") == 0
or fatal("Could not backup $realpub");
system("mv -f $tmpkey $realkey") == 0
or fatal("Could not install $realkey");
system("mv -f $tmppub $realpub") == 0
or fatal("Could not install $realpub");
exit(0);
#
# Caller will catch error and send email.
#
sub fatal {
local($msg) = $_[0];
die("*** $0:\n".
" $msg\n");
}
......@@ -137,9 +137,9 @@ DBQueryFatal("update users set usr_modified=now() ".
"where uid='$target_uid'");
#
# mkacct updates the user pubkeys.
# mkacct updates the keys.
#
#SUEXEC($uid, $TBADMINGROUP, "webmkacct -a $target_uid", 0);
SUEXEC($uid, $TBADMINGROUP, "webmkacct -a -f $target_uid", 0);
header("Location: showsfskeys.php3?target_uid=$target_uid");
......
......@@ -301,7 +301,7 @@ TBMAIL("$targuid_name <$targuid_email>",
#
# mkacct arranges for nodes to be updated.
#
#SUEXEC($uid, $TBADMINGROUP, "webmkacct -a $target_uid", 0);
SUEXEC($uid, $TBADMINGROUP, "webmkacct -a -f $target_uid", 0);
header("Location: showsfskeys.php3?target_uid=$target_uid&finished=1");
?>
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