Commit 282eee4f authored by Leigh Stoller's avatar Leigh Stoller

console_setup code, called out of nalloc and nfree. Two parts. A setuid

script runs out of nalloc and nfree and figures out what project (group)
a node is in. It does an ssh over to plastic to run the other script
that does the actual work.
parent 8e3332df
......@@ -6,6 +6,11 @@ $(INSTALL_BINDIR)/%: %
-mkdir -p $(INSTALL_BINDIR)
$(INSTALL_PROGRAM) $< $@
$(INSTALL_SBINDIR)/%: %
@echo "Installing $<"
-mkdir -p $(INSTALL_SBINDIR)
$(INSTALL_PROGRAM) $< $@
$(INSTALL_BINDIR)/%: %.tcl
@echo "Installing $<"
-mkdir -p $(INSTALL_BINDIR)
......@@ -16,3 +21,5 @@ $(INSTALL_LIBDIR)/%: %
-mkdir -p $(INSTALL_LIBDIR)
$(INSTALL_PROGRAM) $< $@
CFLAGS += $(LOCALCFLAGS)
......@@ -10,5 +10,6 @@ INSTALL_DATA = ${INSTALL} -m 444
INSTALL_DIR = $(exec_prefix)
INSTALL_BINDIR = $(exec_prefix)/bin
INSTALL_SBINDIR = $(exec_prefix)/sbin
INSTALL_LIBDIR = $(exec_prefix)/lib
INSTALL_WWWDIR = $(exec_prefix)/www
......@@ -5,6 +5,8 @@ my $dbh = Mysql->connect("localhost","tbdb","script","none");
if ($#ARGV < 1) {die("Usage: nalloc <pid> <eid> <node> <node> <...>\n");}
my $TB="/usr/testbed/bin";
my $consetup="$TB/console_setup";
my $error = 0;
my $pid = shift;
my $eid = shift;
......@@ -48,6 +50,8 @@ foreach my $n (@node_names) {
$sth = $dbh->query($cmd) && print "Succeeded.\n"
|| (print "Failed Command:\n$cmd\nError string is:".$dbh->errstr."\n"
&& $error++);
system("$consetup $n") == 0 or
print STDERR "WARNING: $consetup $n failed!";
}
exit($error);
......@@ -11,6 +11,7 @@ if ($#ARGV < 1) {
my $error = 0;
my $TB="/usr/testbed/bin";
my $consetup="$TB/console_setup";
my $osload="$TB/os_load";
my $reloadpid="testbed";
my $reloadeid="reloading";
......@@ -106,6 +107,8 @@ foreach my $n (@node_names) {
&& $error++);
}
system("$consetup $n") == 0 or
print STDERR "WARNING: $consetup $n failed!";
}
foreach $reload ( keys(%reloads)) {
......
......@@ -13,7 +13,8 @@ SCRIPTS = mkprojdir_wrapper tbdoit tbstopit mkexpdir \
sched_reload os_setup
DATAFILES = default.ifc
SUSCRIPTS = mkprojdir rmprojdir os_setup mkacct rmacct \
mkacct-ctrl rmacct-ctrl ifc_setup os_load
mkacct-ctrl rmacct-ctrl ifc_setup os_load console_setup
SBINSCRIPTS = console_setup.proxy
all: $(BINS) $(SUBDIRS)
......@@ -41,7 +42,8 @@ subdir-install:
script-install: $(addprefix $(INSTALL_BINDIR)/, $(SCRIPTS)) \
$(addprefix $(INSTALL_BINDIR)/, $(SUSCRIPTS)) \
$(addprefix $(INSTALL_LIBTBDIR)/, $(SCRIPTS)) \
$(addprefix $(INSTALL_LIBTBDIR)/, $(DATAFILES))
$(addprefix $(INSTALL_LIBTBDIR)/, $(DATAFILES)) \
$(addprefix $(INSTALL_SBINDIR)/, $(SBINSCRIPTS))
#
# Leave these rules here. They should be flushed when we no longer
......@@ -94,6 +96,10 @@ post-install:
chmod u+s $(INSTALL_BINDIR)/delay_setup
chown root $(INSTALL_LIBTBDIR)/delay_setup
chmod u+s $(INSTALL_LIBTBDIR)/delay_setup
chown root $(INSTALL_BINDIR)/console_setup
chmod u+s $(INSTALL_BINDIR)/console_setup
chown root $(INSTALL_LIBTBDIR)/console_setup
chmod u+s $(INSTALL_LIBTBDIR)/console_setup
clean:
rm -f *.o $(BINS) core
#!/usr/bin/perl -wT
use English;
#
# usage: console_setup node [node node ...]
#
my $SSH = "sshtb -q -l root plastic.cs.utah.edu";
my $PROG = "/usr/testbed/sbin/console_setup.proxy";
my $TBPID = "flux";
my $dbg = 1;
my $cmdargs = "";
my @row;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Set up for querying the database.
#
use Mysql;
my $DB = Mysql->connect("localhost", "tbdb", "script", "none");
if ( $#ARGV < 0 ) {
die("Usage: console_setup node [nodes ... ]\n".
"Enables project members to access consoles logs of nodes.\n");
}
my @nodes = @ARGV;
#
# Script must be setuid root. We don't worry about who called us or what
# nodes are specified since this script always does the right thing.
#
if ($EUID != 0) {
die("Must be run as root");
}
#
# Build of a list of nodes/pid pairs and then send the command over to
# plastic.
#
foreach my $node (@nodes) {
#
# Untaint the argument.
#
if ($node =~ /^([-\@\w.]+)$/) {
$node = $1;
}
#
# Need the project for the node since that is the group.
#
$db_result = $DB->query("select pid from reserved where node_id='$node'");
if ($db_result->numrows == 1) {
@row = $db_result->fetchrow_array();
$pid = $row[0];
}
else {
$pid = $TBPID;
}
$cmdargs = "$cmdargs $node $pid";
}
$UID = 0;
system("$SSH $PROG $cmdargs") == 0 or
die("Failed: $SSH $PROG $cmdargs: $?");
exit 0;
#!/usr/bin/perl -wT
use English;
#
# usage: console_setup node1 pid1 node2 pid2 ...
#
# This script runs on plastic where the tip lines are and the capture
# processes are running. Since plastic does not have access to the DB
# we invoke this from paper in nalloc/nfree, giving it a list of node/pid
# pairs to set. Only use can run this script.
#
my $TB = "/usr/testbed/bin";
my $TIPLOGDIR = "/var/log/tiplogs";
my $TIPDEVDIR = "/dev/tip";
my $TBPID = "flux";
my $dbg = 1;
my %nodepid = ();
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
sub usage {
die("Usage: console_setup node project_id [node pid node pid ...]\n".
"Enables project members to access consoles logs of nodes.\n".
"This script must be run as root, typically from paper.\n");
}
if ( $#ARGV < 1) {
usage();
}
while ($#ARGV >= 0) {
if ($#ARGV < 1) {
usage();
}
$node = shift;
$pid = shift;
# untaint the args.
if ($node =~ /^([-\@\w.]+)$/) {
$node = $1;
}
if ($pid =~ /^([-\@\w.]+)$/) {
$pid = $1;
}
$nodepid{$node} = $pid;
}
#
# This script must be run as root, typically from paper.
#
if ($UID != 0) {
die("Must be run as root.");
}
if (! chdir($TIPLOGDIR)) {
die("Could not chdir to $TIPLOGDIR: $!\n");
}
#
# Well, do it.
#
foreach my $node ( keys %nodepid ) {
$pid = $nodepid{$node};
#
# Find out the current group setting for the file.
#
$filename = "${node}.run";
if (! -e $filename) {
die("Console log $filename for $node does not exist!");
}
# This is silly! Is there a better way to do this?
(undef,undef,undef,undef,undef,$gid) = stat($filename);
#
# If the file is already in the correct group skip it since there no point
# in rolling the file. Inconvenient for the user to have the log keep
# rolling.
#
if (getgrgid($gid) eq $pid) {
next;
}
unlink($filename) or
die("Could not unlink run file $filename");
#
# Now send a USR1 signal to the capture process so that it opens
# a new run file.
#
$procid = `cat ${node}.pid`;
$procid =~ s/\n//;
# untaint
if ($procid =~ /^([-\@\w.]+)$/) {
$procid = $1;
}
kill('USR1', $procid) or
die("Could not signal(USR1) process $procid for log $filename");
# Give capture the chance to react.
sleep(1);
#
# If the file does not exist, touch it. We have this problem with
# capture getting blocked.
#
if (! -e $filename) {
system("touch $filename");
}
#
# The new log should exist now. Set its group, and just to be safe
# set its mode too.
#
$gid = getgrnam($pid);
chown(0, $gid, $filename) or
die("Could not chown(0, $gid) $filename: $!");
chmod(0640, $filename) or
die("Could not chmod(0640) $filename: $!");
#
# Now send a USR2 signal to the capture process so that it closes down
# any tip thats attached to it.
#
kill('USR2', $procid) or
die("Could not signal(USR2) process $procid for log $filename");
#
# Set the mode and group for the tty that tip is going to use. This
# allows the user to access the tip line using a non-setuid version
# of tip.
#
$tipdevname = "$TIPDEVDIR/$node";
chown(0, $gid, $tipdevname) or
die("Could not chown(0, $gid) $tipdevname: $!");
chmod(0660, $tipdevname) or
die("Could not chmod(0660) $tipdevname: $!");
}
exit 0;
#!/usr/bin/perl -wT
use English;
#
# usage: console_setup node1 pid1 node2 pid2 ...
#
# This script runs on plastic where the tip lines are and the capture
# processes are running. Since plastic does not have access to the DB
# we invoke this from paper in nalloc/nfree, giving it a list of node/pid
# pairs to set. Only use can run this script.
#
my $TB = "/usr/testbed/bin";
my $TIPLOGDIR = "/var/log/tiplogs";
my $TIPDEVDIR = "/dev/tip";
my $TBPID = "flux";
my $dbg = 1;
my %nodepid = ();
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
sub usage {
die("Usage: console_setup node project_id [node pid node pid ...]\n".
"Enables project members to access consoles logs of nodes.\n".
"This script must be run as root, typically from paper.\n");
}
if ( $#ARGV < 1) {
usage();
}
while ($#ARGV >= 0) {
if ($#ARGV < 1) {
usage();
}
$node = shift;
$pid = shift;
# untaint the args.
if ($node =~ /^([-\@\w.]+)$/) {
$node = $1;
}
if ($pid =~ /^([-\@\w.]+)$/) {
$pid = $1;
}
$nodepid{$node} = $pid;
}
#
# This script must be run as root, typically from paper.
#
if ($UID != 0) {
die("Must be run as root.");
}
if (! chdir($TIPLOGDIR)) {
die("Could not chdir to $TIPLOGDIR: $!\n");
}
#
# Well, do it.
#
foreach my $node ( keys %nodepid ) {
$pid = $nodepid{$node};
#
# Find out the current group setting for the file.
#
$filename = "${node}.run";
if (! -e $filename) {
die("Console log $filename for $node does not exist!");
}
# This is silly! Is there a better way to do this?
(undef,undef,undef,undef,undef,$gid) = stat($filename);
#
# If the file is already in the correct group skip it since there no point
# in rolling the file. Inconvenient for the user to have the log keep
# rolling.
#
if (getgrgid($gid) eq $pid) {
next;
}
unlink($filename) or
die("Could not unlink run file $filename");
#
# Now send a USR1 signal to the capture process so that it opens
# a new run file.
#
$procid = `cat ${node}.pid`;
$procid =~ s/\n//;
# untaint
if ($procid =~ /^([-\@\w.]+)$/) {
$procid = $1;
}
kill('USR1', $procid) or
die("Could not signal(USR1) process $procid for log $filename");
# Give capture the chance to react.
sleep(1);
#
# If the file does not exist, touch it. We have this problem with
# capture getting blocked.
#
if (! -e $filename) {
system("touch $filename");
}
#
# The new log should exist now. Set its group, and just to be safe
# set its mode too.
#
$gid = getgrnam($pid);
chown(0, $gid, $filename) or
die("Could not chown(0, $gid) $filename: $!");
chmod(0640, $filename) or
die("Could not chmod(0640) $filename: $!");
#
# Now send a USR2 signal to the capture process so that it closes down
# any tip thats attached to it.
#
kill('USR2', $procid) or
die("Could not signal(USR2) process $procid for log $filename");
#
# Set the mode and group for the tty that tip is going to use. This
# allows the user to access the tip line using a non-setuid version
# of tip.
#
$tipdevname = "$TIPDEVDIR/$node";
chown(0, $gid, $tipdevname) or
die("Could not chown(0, $gid) $tipdevname: $!");
chmod(0660, $tipdevname) or
die("Could not chmod(0660) $tipdevname: $!");
}
exit 0;
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