Commit bc81c383 authored by Leigh Stoller's avatar Leigh Stoller

The bulk of Emulab Portal Support! See this wiki page for a high level

view of what Portal support does:

https://users.emulab.net/trac/emulab/wiki/Portal

Notes:

* New DB tables to store the list of peer emulabs, and exports info
  for users and projects.

* Backend script to manage user and projects exports.

* Cross site login from the portal; users do not login into the peer
  sites directly.

* New portal_daemon to run on the portal, to handle exports and
  updates.
parent 7b62628f
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2009 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -13,9 +13,10 @@ UNIFIED = @UNIFIED_BOSS_AND_OPS@
include $(OBJDIR)/Makeconf
SBIN_STUFF = tbacct addsfskey addpubkey mkusercert quotamail genpubkeys \
newuser newproj mksyscert spewcert
newuser newproj mksyscert spewcert dumpuser dumpproject \
manageremote
LIBEXEC_STUFF = webtbacct webaddsfskey webaddpubkey webmkusercert \
webnewuser webnewproj webspewcert
webnewuser webnewproj webspewcert webmanageremote
CTRLSBIN_STUFF = adduserhook
# These scripts installed setuid, with sudo.
......@@ -23,6 +24,11 @@ SETUID_BIN_SCRIPTS =
SETUID_SBIN_SCRIPTS = tbacct addpubkey mkusercert mksyscert
SETUID_LIBX_SCRIPTS =
ifeq ($(PROTOGENI_SUPPORT),1)
SBIN_STUFF += manageremote
SETUID_SBIN_SCRIPTS += manageremote
endif
#
# Targets
#
......
This diff is collapsed.
......@@ -817,7 +817,9 @@ DYNAMICROOTPASSWORDS
TPM
REMOTEWIKIDOCS
PROTOGENI_SUPPORT
PROTOGENI_CLEARINGHOUSE
PROTOGENI_WEBSITE
PROTOGENI_ISCLEARINGHOUSE
PROTOGENI_EMAIL
PROTOGENI_DOMAIN
PROTOGENI_RPCPORT
PROTOGENI_RPCNAME
......@@ -833,6 +835,8 @@ TBUSEDBI
NEEDMROUTED
OPSVM_ENABLE
OPSVM_MOUNTPOINT
PORTAL_ENABLE
PORTAL_ISPRIMARY
TBOPSEMAIL
TBOPSEMAIL_NOSLASH
TBROBOCOPSEMAIL
......@@ -4959,6 +4963,10 @@ done
......@@ -5048,7 +5056,9 @@ DYNAMICROOTPASSWORDS=1
TPM=0
REMOTEWIKIDOCS=1
PROTOGENI_SUPPORT=0
PROTOGENI_CLEARINGHOUSE=0
PROTOGENI_ISCLEARINGHOUSE=0
PROTOGENI_EMAIL="geni-dev-utah@flux.utah.edu"
PROTOGENI_WEBSITE="www.emulab.net"
PROTOGENI_DOMAIN="unknown"
PROTOGENI_RPCPORT=12369
PROTOGENI_RPCNAME=""
......@@ -5063,6 +5073,8 @@ NEEDMROUTED=0
OPSVM_ENABLE=0
OPSVM_MOUNTPOINT="/ops"
OURTIMEZONE="America/Denver"
PORTAL_ENABLE=0
PORTAL_ISPRIMARY=0
#
# XXX You really don't want to change these!
......@@ -5414,6 +5426,9 @@ else
TBERRORSEMAIL_NOSLASH="$TBOPSEMAIL_NOSLASH"
TBERRORSEMAIL="$TBOPSEMAIL"
fi
if test -n "$PROTOGENI_EMAIL"; then
PROTOGENI_EMAIL="`echo $PROTOGENI_EMAIL | sed -e 's/@/\\\@/'`"
fi
# Default OURDOMAIN to the domain name of the boss node
# This is gross beyond all description - autoconf changes m4's quote characters
......
......@@ -215,7 +215,9 @@ AC_SUBST(DYNAMICROOTPASSWORDS)
AC_SUBST(TPM)
AC_SUBST(REMOTEWIKIDOCS)
AC_SUBST(PROTOGENI_SUPPORT)
AC_SUBST(PROTOGENI_CLEARINGHOUSE)
AC_SUBST(PROTOGENI_WEBSITE)
AC_SUBST(PROTOGENI_ISCLEARINGHOUSE)
AC_SUBST(PROTOGENI_EMAIL)
AC_SUBST(PROTOGENI_DOMAIN)
AC_SUBST(PROTOGENI_RPCPORT)
AC_SUBST(PROTOGENI_RPCNAME)
......@@ -231,6 +233,8 @@ AC_SUBST(TBUSEDBI)
AC_SUBST(NEEDMROUTED)
AC_SUBST(OPSVM_ENABLE)
AC_SUBST(OPSVM_MOUNTPOINT)
AC_SUBST(PORTAL_ENABLE)
AC_SUBST(PORTAL_ISPRIMARY)
#
# Offer both versions of the email addresses that have the @ escaped
......@@ -316,7 +320,9 @@ DYNAMICROOTPASSWORDS=1
TPM=0
REMOTEWIKIDOCS=1
PROTOGENI_SUPPORT=0
PROTOGENI_CLEARINGHOUSE=0
PROTOGENI_ISCLEARINGHOUSE=0
PROTOGENI_EMAIL="geni-dev-utah@flux.utah.edu"
PROTOGENI_WEBSITE="www.emulab.net"
PROTOGENI_DOMAIN="unknown"
PROTOGENI_RPCPORT=12369
PROTOGENI_RPCNAME=""
......@@ -331,6 +337,8 @@ NEEDMROUTED=0
OPSVM_ENABLE=0
OPSVM_MOUNTPOINT="/ops"
OURTIMEZONE="America/Denver"
PORTAL_ENABLE=0
PORTAL_ISPRIMARY=0
#
# XXX You really don't want to change these!
......@@ -531,6 +539,9 @@ else
TBERRORSEMAIL_NOSLASH="$TBOPSEMAIL_NOSLASH"
TBERRORSEMAIL="$TBOPSEMAIL"
fi
if test -n "$PROTOGENI_EMAIL"; then
PROTOGENI_EMAIL="`echo $PROTOGENI_EMAIL | sed -e 's/@/\\\@/'`"
fi
# Default OURDOMAIN to the domain name of the boss node
# This is gross beyond all description - autoconf changes m4's quote characters
......
......@@ -88,7 +88,11 @@ PROTOGENI_SUPPORT=1
# If you are not the main Emulab site in Utah, change this!
PROTOGENI_DOMAIN="utahemulab"
# If you are not the main Emulab site in Utah, DO NOT SET THIS!
PROTOGENI_CLEARINGHOUSE=1
PROTOGENI_ISCLEARINGHOUSE=1
# Set this to the email address for ClearingHouse.
PROTOGENI_EMAIL="geni-dev-utah@flux.utah.edu"
# Set this to the hostname of the clearinghouse web site.
PROTOGENI_WEBSITE="www.emulab.net"
#
# SSL Certificate stuff. Used to customize config files in ssl directory.
......
......@@ -12,3 +12,6 @@ TBSTATEDEMAIL=stoller@fast.cs.utah.edu
TBTESTSUITEEMAIL=stoller@fast.cs.utah.edu
WWW=www.emulab.net/dev/stoller
THISHOMEBASE=Stoller.Emulab.Net
PORTAL_ENABLE=1
PORTAL_ISPRIMARY=1
#
# Another change to the testbed startup script.
#
use strict;
use libinstall;
my $TESTBED_STARTUP = "/usr/local/etc/rc.d/3.testbed.sh";
sub InstallUpdate($$)
{
my ($version, $phase) = @_;
#
# If something should run in the pre-install phase.
#
if ($phase eq "pre") {
Phase "startupfile", "Updating testbed startup file", sub {
DoneIfIdentical("$TOP_OBJDIR/rc.d/3.testbed.sh", $TESTBED_STARTUP);
DiffFiles("$TOP_OBJDIR/rc.d/3.testbed.sh", $TESTBED_STARTUP);
ExecQuietFatal("$GMAKE -C $TOP_OBJDIR/rc.d install");
};
}
#
# If something should run in the post-install phase.
#
if ($phase eq "post") {
}
return 0;
}
1;
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm \
GeniComponent.pm GeniCH.pm GeniEmulabUtil.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \
GeniUtil.pm GeniRegistry.pm GeniUsage.pm GeniHRN.pm \
GeniSES.pm GeniResource.pm GeniXML.pm GeniAM.pm
GeniSES.pm GeniResource.pm GeniXML.pm GeniAM.pm GeniEmulab.pm
SBIN_SCRIPTS = plabnodewrapper plabslicewrapper
SCRIPTS = genischemacheck.pl
......
This diff is collapsed.
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -21,7 +21,7 @@ SETUID_LIBX_SCRIPTS =
# configure if the .in file is changed.
#
all: Genixmlrpc.pm GeniResponse.pm \
protogeni-ch.pm protogeni-sa.pm protogeni-cm.pm \
protogeni-ch.pm protogeni-sa.pm protogeni-cm.pm protogeni-emulab.pm \
protogeni-ses.pm geni-am.pm \
protogeni-wrapper.pl
......@@ -33,6 +33,7 @@ install-libs: $(INSTALL_LIBDIR)/Genixmlrpc.pm \
$(INSTALL_LIBDIR)/protogeni-sa.pm \
$(INSTALL_LIBDIR)/protogeni-cm.pm \
$(INSTALL_LIBDIR)/protogeni-ses.pm \
$(INSTALL_LIBDIR)/protogeni-emulab.pm \
$(INSTALL_LIBDIR)/geni-am.pm \
$(INSTALL_DIR)/opsdir/lib/Genixmlrpc.pm \
$(INSTALL_DIR)/opsdir/lib/GeniResponse.pm
......@@ -41,7 +42,7 @@ install-scripts: $(INSTALL_DIR)/protogeni/xmlrpc/protogeni-wrapper.pl
$(SUDO) chown root $(INSTALL_DIR)/protogeni/xmlrpc/protogeni-wrapper.pl
$(SUDO) chmod u+s $(INSTALL_DIR)/protogeni/xmlrpc/protogeni-wrapper.pl
install: install-libs install-scripts
install: all install-libs install-scripts
control-install:
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
# Do this early so that we talk to the right DB.
use vars qw($GENI_DBNAME $GENI_METHODS $EMULAB_PEMFILE);
BEGIN { $GENI_DBNAME = "geni"; }
# Configure variables
my $ETCDIR = "@prefix@/etc";
$EMULAB_PEMFILE = "$ETCDIR/genisa.pem";
# Testbed libraries.
use lib '@prefix@/lib';
use GeniEmulab;
$GENI_METHODS = {
"GetVersion" => \&GeniEmulab::GetVersion,
"AddUser" => \&GeniEmulab::AddUser,
"DeleteUser" => \&GeniEmulab::DeleteUser,
"ModifyUser" => \&GeniEmulab::ModifyUser,
"AddProject" => \&GeniEmulab::AddProject,
"AddGroup" => \&GeniEmulab::AddGroup,
"SetGroups" => \&GeniEmulab::SetGroups,
"CrossLogin" => \&GeniEmulab::CrossLogin,
};
1;
......@@ -30,8 +30,10 @@ BEGIN {
}
# Configure variables
my $MAINSITE = @TBMAINSITE@;
my $TBOPS = "@TBOPSEMAIL@";
my $MAINSITE = @TBMAINSITE@;
my $TBOPS = "@TBOPSEMAIL@";
my $PORTAL_ENABLE = @PORTAL_ENABLE@;
my $PORTAL_ISPRIMARY = @PORTAL_ISPRIMARY@;
my $MODULE;
my $GENIURN;
......@@ -45,7 +47,10 @@ my %GENI_MODULES = ( "cm" => "@prefix@/lib/protogeni-cm.pm",
"ses" => "@prefix@/lib/protogeni-ses.pm",
# XXX This is temporary!
"instools" => "@prefix@/lib/protogeni-instools.pm",
);
);
if ($PORTAL_ENABLE && !$PORTAL_ISPRIMARY) {
$GENI_MODULES{"emulab"} = "@prefix@/lib/protogeni-emulab.pm";
}
# These variables are shared with the loaded module.
use vars qw($EMULAB_PEMFILE $GENI_METHODS $GENI_VERSION
......@@ -62,10 +67,6 @@ use libEmulab;
use libtestbed;
use User;
# Geniuser.
my $user = "geniuser";
my $group = "GeniSlices";
# Need a command line option.
my $debug = 0;
my $mailerrors = 1;
......@@ -138,19 +139,7 @@ if (! (exists($ENV{'SSL_CLIENT_VERIFY'}) &&
# so that there is an emulab user context, or many of the scripts we
# invoke will complain and croak.
#
my $unix_uid = getpwnam("$user") or
die("*** $0:\n".
" No such user $user\n");
my $unix_gid = getgrnam("$group") or
die("*** $0:\n".
" No such group $group\n");
# Flip to user and never go back
$GID = $unix_gid;
$EGID = "$unix_gid $unix_gid";
$EUID = $UID = $unix_uid;
$ENV{'USER'} = $user;
$ENV{'LOGNAME'} = $user;
GeniUtil::FlipToGeniUser();
if (exists($ENV{'PATH_INFO'}) && $ENV{'PATH_INFO'} ne "") {
my $pathinfo = $ENV{'PATH_INFO'};
......@@ -261,6 +250,10 @@ if (!(defined($GENI_METHODS) && defined($EMULAB_PEMFILE))) {
#
# So we know who/what we are acting as.
#
# Must be a require cause of the DB name that is set in the module file
# which is not loaded until just above.
require GeniCertificate;
my $certificate = GeniCertificate->LoadFromFile($EMULAB_PEMFILE);
if (!defined($certificate)) {
......@@ -374,6 +367,9 @@ if ($MODULE eq "cm" || $MODULE eq $AM_MODULE) {
$debug = 2;
}
}
elsif ($MODULE eq "emulab") {
$debug = 2;
}
my $starttime = [gettimeofday()];
eval { $result = &{ $GENI_METHODS->{$method} }(@{ $call->{'value'} }) };
......
......@@ -590,6 +590,20 @@ CREATE TABLE `emulab_locks` (
PRIMARY KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `emulab_peers`
--
DROP TABLE IF EXISTS `emulab_peers`;
CREATE TABLE `emulab_peers` (
`name` varchar(64) NOT NULL default '',
`urn` varchar(128) NOT NULL default '',
`is_primary` tinyint(1) NOT NULL default '0',
`weburl` tinytext,
PRIMARY KEY (`name`),
UNIQUE KEY `urn` (`urn`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `emulab_pubs`
--
......@@ -1482,6 +1496,23 @@ CREATE TABLE `global_vtypes` (
PRIMARY KEY (`vtype`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `group_exports`
--
DROP TABLE IF EXISTS `group_exports`;
CREATE TABLE `group_exports` (
`pid_idx` mediumint(8) unsigned NOT NULL default '0',
`gid_idx` mediumint(8) unsigned NOT NULL default '0',
`pid` varchar(48) NOT NULL default '',
`gid` varchar(32) NOT NULL default '',
`peer` varchar(64) NOT NULL default '',
`exported` datetime default NULL,
`updated` datetime default NULL,
PRIMARY KEY (`pid_idx`,`gid_idx`,`peer`),
UNIQUE KEY pidpeer (`pid`,`gid`,`peer`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `group_features`
--
......@@ -3332,6 +3363,7 @@ CREATE TABLE `projects` (
`allow_workbench` tinyint(1) NOT NULL default '0',
`nonlocal_id` varchar(128) default NULL,
`nonlocal_type` tinytext,
`manager_urn` varchar(128) default NULL,
PRIMARY KEY (`pid_idx`),
UNIQUE KEY `pid` (`pid`),
KEY `unix_gid` (`unix_gid`),
......@@ -3813,6 +3845,21 @@ CREATE TABLE `unixgroup_membership` (
PRIMARY KEY (`uid`,`gid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `user_exports`
--
DROP TABLE IF EXISTS `user_exports`;
CREATE TABLE `user_exports` (
`uid` varchar(8) NOT NULL default '',
`uid_idx` mediumint(8) unsigned NOT NULL default '0',
`peer` varchar(64) NOT NULL default '',
`exported` datetime default NULL,
`updated` datetime default NULL,
PRIMARY KEY (`uid_idx`,`peer`),
UNIQUE KEY uidpeer (`uid`,`peer`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `user_features`
--
......@@ -3981,6 +4028,7 @@ CREATE TABLE `users` (
`mailman_password` tinytext,
`nonlocal_id` varchar(128) default NULL,
`nonlocal_type` tinytext,
`manager_urn` varchar(128) default NULL,
`default_project` mediumint(8) unsigned default NULL,
`nocollabtools` tinyint(1) default '0',
PRIMARY KEY (`uid_idx`),
......
......@@ -757,9 +757,13 @@ REPLACE INTO table_regex VALUES ('projects','default_user_interface','text','reg
REPLACE INTO table_regex VALUES ('projects','pid','text','regex','^[-\\w]+$',2,48,NULL);
REPLACE INTO table_regex VALUES ('projects','pid_idx','text','regex','^[\\d]+$',1,12,NULL);
REPLACE INTO table_regex VALUES ('projects','URL','text','redirect','default:tinytext',0,0,NULL);
REPLACE INTO table_regex VALUES ('projects','manager_urn','text','regex','^[-_\\w\\.\\/:+]*$',10,128,NULL);
REPLACE INTO table_regex VALUES ('projects','nonlocal_id','text','regex','^[-_\\w\\.\\/:+]*$',10,128,NULL);
REPLACE INTO table_regex VALUES ('projects','nonlocal_type','text','regex','^[-\\w]*$',1,64,NULL);
REPLACE INTO table_regex VALUES ('reserved','vname','text','redirect','virt_nodes:vname',1,32,NULL);
REPLACE INTO table_regex VALUES ('users','manager_urn','text','regex','^[-_\\w\\.\\/:+]*$',10,128,NULL);
REPLACE INTO table_regex VALUES ('users','nonlocal_id','text','regex','^[-_\\w\\.\\/:+]*$',10,128,NULL);
REPLACE INTO table_regex VALUES ('users','nonlocal_type','text','regex','^[-\\w]*$',1,64,NULL);
REPLACE INTO table_regex VALUES ('users','uid','text','regex','^[a-zA-Z][\\w]+$',2,8,NULL);
REPLACE INTO table_regex VALUES ('users','uid_idx','text','regex','^[\\d]+$',1,12,NULL);
REPLACE INTO table_regex VALUES ('users','usr_phone','text','regex','^[-\\d\\(\\)\\+\\.x ]+$',7,64,NULL);
......
#
#
#
use strict;
use libdb;
my $impotent = 0;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (! DBTableExists("emulab_peers")) {
DBQueryFatal("CREATE TABLE `emulab_peers` ( ".
" `name` varchar(64) NOT NULL default '', ".
" `urn` varchar(128) NOT NULL default '', ".
" `is_primary` tinyint(1) NOT NULL default '0', ".
" `weburl` tinytext, ".
" PRIMARY KEY (`name`), ".
" UNIQUE KEY `urn` (`urn`) ".
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
}
if (! DBTableExists("group_exports")) {
DBQueryFatal("CREATE TABLE `group_exports` ( ".
" `pid_idx` mediumint(8) unsigned NOT NULL default '0', ".
" `gid_idx` mediumint(8) unsigned NOT NULL default '0', ".
" `pid` varchar(48) NOT NULL default '', ".
" `gid` varchar(32) NOT NULL default '', ".
" `peer` varchar(64) NOT NULL default '', ".
" `exported` datetime default NULL, ".
" `updated` datetime default NULL, ".
" PRIMARY KEY (`pid_idx`,`gid_idx`,`peer`), ".
" UNIQUE KEY pidpeer (`pid`,`gid`,`peer`) ".
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
}
if (! DBTableExists("user_exports")) {
DBQueryFatal("CREATE TABLE `user_exports` ( ".
" `uid` varchar(8) NOT NULL default '', ".
" `uid_idx` mediumint(8) unsigned NOT NULL default '0', ".
" `peer` varchar(64) NOT NULL default '', ".
" `exported` datetime default NULL, ".
" `updated` datetime default NULL, ".
" PRIMARY KEY (`uid_idx`,`peer`), ".
" UNIQUE KEY uidpeer (`uid`,`peer`) ".
") ENGINE=MyISAM DEFAULT CHARSET=latin1");
}
if (!DBSlotExists("projects", "manager_urn")) {
DBQueryFatal("alter table projects add ".
" `manager_urn` varchar(128) default NULL ".
" after nonlocal_type");
}
if (!DBSlotExists("users", "manager_urn")) {
DBQueryFatal("alter table users add ".
" `manager_urn` varchar(128) default NULL ".
" after nonlocal_type");
}
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('users','manager_urn','text','regex', ".
" '^[-_\\\\w\\\\.\\\\/:+]*\$',10,128,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('projects','manager_urn','text','regex', ".
" '^[-_\\\\w\\\\.\\\\/:+]*\$',10,128,NULL)");
# These were left out of an earlier update.
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('users','nonlocal_id','text','regex', ".
" '^[-_\\\\w\\\\.\\\\/:+]*\$',10,128,NULL)");
DBQueryFatal("REPLACE INTO table_regex VALUES ".
" ('users','nonlocal_type','text','regex', ".
" '^[-\\\\w]*\$',1,64,NULL)");
return 0;
}
......@@ -12,6 +12,7 @@ UNIFIED = @UNIFIED_BOSS_AND_OPS@
PLABSUPPORT = @PLABSUPPORT@
ISMAINSITE = @TBMAINSITE@
NSVERIFY = @NSVERIFY@
PORTAL_ISPRIMARY= @PORTAL_ISPRIMARY@
SYSTEM := $(shell uname -s)
include $(OBJDIR)/Makeconf
......@@ -44,11 +45,14 @@ SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
elabinelab snmpit.proxy panic node_attributes \
nfstrace plabinelab smbpasswd_setup smbpasswd_setup.proxy \
rmproj snmpit.proxynew snmpit.proxyv2 pool_daemon \
checknodes_daemon snmpit.proxyv3
checknodes_daemon snmpit.proxyv3
ifeq ($(ISMAINSITE),1)
SBIN_STUFF += repos_daemon
endif
ifeq ($(PORTAL_ISPRIMARY),1)
SBIN_STUFF += portal_daemon
endif
CTRLSBIN_STUFF = console_setup.proxy sfskey_update.proxy \
savelogs.proxy eventsys.proxy
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2009-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
use Getopt::Std;
#
# Attempt to determine if nodes are really messed up.
#
sub usage()
{
print "Usage: portal_daemon [-d]\n";
exit(1);
}
my $optlist = "dn1";
my $debug = 0;
my $impotent = 0;
my $oneshot = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $LOGFILE = "$TB/log/portal_daemon.log";
my $PIDFILE = "/var/run/portal_daemon.pid";
my $SUDO = "/usr/local/bin/sudo";
my $PROTOUSER = "elabman";
my $WAP = "$TB/sbin/withadminprivs";
my $MANAGEREMOTE = "$TB/sbin/manageremote";
my $PORTAL_ENABLE = @PORTAL_ENABLE@;
my $PORTAL_PRIMARY= @PORTAL_ISPRIMARY@;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/site/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Protos
sub fatal($);
sub logit($);
sub notify($);
#
# Turn off line buffering on output
#
$| = 1;
#
# Exit if not a portal.
#
if (! ($PORTAL_ENABLE && $PORTAL_PRIMARY)) {
exit(0);
}
#
# Check args early so we get the right DB.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug++;
}
if (defined($options{"n"})) {
$impotent = 1;
}
if (defined($options{"1"})) {
$oneshot = 1;
}
if ($UID != 0) {
die("Must be root to run this script\n");
}
# Set this to turn off tblog in libraries.
$ENV{'TBLOG_OFF'} = "yep";
# Load the Testbed support stuff.
use lib "@prefix@/lib";
use libEmulab;
use libdb;
use libtestbed;
use Project;
use Group;
use User;
#
# Only one please.
#
if (CheckDaemonRunning("portal_daemon")) {
fatal("Not starting another portal daemon!");
}
#
# We need this user for running below.
#
my $elabman = User->Lookup($PROTOUSER);
if (!defined($elabman)) {
fatal("Could not lookup $PROTOUSER user. Exiting ...");
}
my $protoproj = Project->Lookup(TBOPSPID());
if (!defined($protoproj)) {
fatal("Could not lookup emulab-ops project. Exiting ...");
}
# Go to ground.
if (! $debug) {
if (TBBackGround($LOGFILE)) {
exit(0);
}
}
if (MarkDaemonRunning("portal_daemon")) {
fatal("Could not mark daemon as running!");
}
logit("Portal Daemon starting ... pid $$");
if ($elabman->FlipTo($protoproj->unix_gid())) {
fatal("Could not flipto $elabman");
}
#
# Setup a signal handler for newsyslog.
#
sub handler()
{
my $SAVEEUID = $EUID;
$EUID = 0;
ReOpenLog($LOGFILE);
$EUID = $SAVEEUID;
}
$SIG{HUP} = \&handler
if (!$debug);
#
# Export users from projects.
#
my %users_warned = ();
sub ExportUsers()
{
my $trust_none = $Group::MemberShip::TRUSTSTRING_NONE;
#
# First get a list of projects exports.
#
my $projects_result =
DBQueryWarn("select pid,pid_idx,peer from group_exports ".
"where pid_idx=gid_idx");
return
if (!$projects_result);
#
# For each project, look for users that have not been exported.
#
while (my ($pid,$pid_idx,$peer) = $projects_result->fetchrow_array()) {
my $users_result =
DBQueryWarn("select g.uid,g.uid_idx from group_membership as g ".
"left join user_exports as u on ".
" u.uid_idx=g.uid_idx and peer='$peer' ".
"where g.pid_idx='$pid_idx' and ".
" g.gid_idx=g.pid_idx and ".
" g.trust!='$trust_none' and ".
" u.uid_idx is null");
return
if (!$users_result);
while (my ($uid,$uid_idx) = $users_result->fetchrow_array()) {
my $user = User->Lookup($uid_idx);
if (!defined($user)) {
# Be careful about an email flood.
if (!exists($users_warned{"$uid_idx"})) {
notify("User $uid ($uid_idx) does not exist anymore");
$users_warned{"$uid_idx"} = time();
}
next;
}
logit("Exporting user $uid ($uid_idx) to $peer");
if (!$impotent) {
system("$WAP $MANAGEREMOTE adduser $peer $uid_idx");
if ($?) {
# Be careful about an email flood.
if (!exists($users_warned{"$uid_idx"})) {
notify("Failed to add user $uid ($uid_idx) to $peer");
$users_warned{"$uid_idx"} = time();
}
next;
}
logit("Done");
}
delete($users_warned{"$uid_idx"});
}
}
}
#