Commit 68e019a5 authored by Leigh B Stoller's avatar Leigh B Stoller

Add new status for users, "inactive". Mostly to support not having so

many ZFS mounts on ops. which on the Mothership is on the order of 8000
or so. Deactivate/reactivate a user with:

	boss> wap tbacct deactivate -u <user>
	boss> wap tbacct reactivate -u <user>

Deactivate will set the shell to nologin and set the ZFS mountpoint=none.
Reactivate will undo that. Note that these do not HUP mountd.
parent 57fa9bba
...@@ -49,6 +49,8 @@ sub usage() ...@@ -49,6 +49,8 @@ sub usage()
print " accountsetup checkdotfiles ...\n"; print " accountsetup checkdotfiles ...\n";
print " accountsetup createsshkey ...\n"; print " accountsetup createsshkey ...\n";
print " accountsetup dropfile ...\n"; print " accountsetup dropfile ...\n";
print " accountsetup deactivateuser ...\n";
print " accountsetup reactivateuser ...\n";
exit(1); exit(1);
} }
my $optlist = "dnf"; my $optlist = "dnf";
...@@ -80,6 +82,7 @@ my $CHPASS = "/usr/bin/chpass"; ...@@ -80,6 +82,7 @@ my $CHPASS = "/usr/bin/chpass";
my $CHOWN = "/usr/sbin/chown"; my $CHOWN = "/usr/sbin/chown";
my $CHMOD = "/bin/chmod"; my $CHMOD = "/bin/chmod";
my $MKDIR = "/bin/mkdir"; my $MKDIR = "/bin/mkdir";
my $NOLOGIN = "/sbin/nologin";
my $MV = "/bin/mv"; my $MV = "/bin/mv";
my $ZFS = "/sbin/zfs"; my $ZFS = "/sbin/zfs";
my $KEYGEN = "/usr/bin/ssh-keygen"; my $KEYGEN = "/usr/bin/ssh-keygen";
...@@ -128,6 +131,8 @@ sub DelGroup(); ...@@ -128,6 +131,8 @@ sub DelGroup();
sub DropFile(); sub DropFile();
sub CheckDotFiles(); sub CheckDotFiles();
sub CreateSSHKey(); sub CreateSSHKey();
sub ReactivateUser();
sub DeactivateUser();
sub fatal($); sub fatal($);
sub ZFSexists($); sub ZFSexists($);
sub MakeDir($$); sub MakeDir($$);
...@@ -199,6 +204,14 @@ SWITCH: for ($cmd) { ...@@ -199,6 +204,14 @@ SWITCH: for ($cmd) {
CreateSSHKey(); CreateSSHKey();
last SWITCH; last SWITCH;
}; };
/^deactivateuser$/ && do {
DeactivateUser();
last SWITCH;
};
/^reactivateuser$/ && do {
ReactivateUser();
last SWITCH;
};
# Default # Default
usage(); usage();
} }
...@@ -352,6 +365,53 @@ sub ModifyUser() ...@@ -352,6 +365,53 @@ sub ModifyUser()
return 0; return 0;
} }
#
# Usage: deactivate username
#
sub DeactivateUser()
{
if (@ARGV != 1) {
fatal("deactivateuser: Wrong number of arguments");
}
my $user = shift(@ARGV);
if ($WITHZFS) {
my $zfsdir = $ZFS_ROOT . USERROOT() . "/$user";
if (ZFSexists($zfsdir) &&
mysystem("$ZFS set mountpoint=none $zfsdir")) {
fatal("Could not set ZFS dir $zfsdir to mountpoint=none");
}
}
if (mysystem("$USERMOD $user -s $NOLOGIN")) {
fatal("Could not set shell to $NOLOGIN");
}
return 0;
}
#
# Usage: reactivate username
#
# The shell is changed via ModifyUser (we do not know the correct
# shell here), this is just for ZFS.
#
sub ReactivateUser()
{
if (@ARGV != 1) {
fatal("reactivateuser: Wrong number of arguments");
}
my $user = shift(@ARGV);
if ($WITHZFS) {
my $zfsdir = $ZFS_ROOT . USERROOT() . "/$user";
my $hdir = USERROOT() . "/$user";
if (ZFSexists($zfsdir) &&
mysystem("$ZFS set mountpoint=$hdir $zfsdir")) {
fatal("Could not set ZFS dir $zfsdir to mountpoint=$hdir");
}
}
return 0;
}
# #
# Usage: addproject projname unix_gname unix_gid unix_uid # Usage: addproject projname unix_gname unix_gid unix_uid
# #
......
...@@ -171,6 +171,8 @@ sub UpdateWindowsPassword(); ...@@ -171,6 +171,8 @@ sub UpdateWindowsPassword();
sub UpdateUser(;$); sub UpdateUser(;$);
sub FreezeUser(); sub FreezeUser();
sub ThawUser(); sub ThawUser();
sub DeactivateUser();
sub ReactivateUser();
sub VerifyUser(); sub VerifyUser();
sub UpdateEmail(); sub UpdateEmail();
sub CheckDotFiles(); sub CheckDotFiles();
...@@ -225,7 +227,7 @@ else { ...@@ -225,7 +227,7 @@ else {
die("Tainted argument: $user\n"); die("Tainted argument: $user\n");
} }
if ($cmd =~ if ($cmd =~
/^(add|del|mod|freeze|passwd|wpasswd|thaw|email|verify|revoke|dots)$/) { /^(add|del|mod|freeze|passwd|wpasswd|thaw|email|verify|revoke|dots|deactivate|reactivate)$/) {
$cmd = $1; $cmd = $1;
} }
else { else {
...@@ -350,6 +352,14 @@ SWITCH: for ($cmd) { ...@@ -350,6 +352,14 @@ SWITCH: for ($cmd) {
ThawUser(); ThawUser();
last SWITCH; last SWITCH;
}; };
/^deactivate$/ && do {
DeactivateUser();
last SWITCH;
};
/^reactivate$/ && do {
ReactivateUser();
last SWITCH;
};
/^revoke$/ && do { /^revoke$/ && do {
RevokeUser(); RevokeUser();
last SWITCH; last SWITCH;
...@@ -862,8 +872,8 @@ sub UpdateUser(;$) ...@@ -862,8 +872,8 @@ sub UpdateUser(;$)
# If doing a modification to a frozen user, then just ignore # If doing a modification to a frozen user, then just ignore
# it; the modification will happen later when the user is thawed. # it; the modification will happen later when the user is thawed.
# #
if ($status eq USERSTATUS_FROZEN) { if ($status eq USERSTATUS_FROZEN || $status eq USERSTATUS_INACTIVE) {
print "Ignoring update of frozen user $user\n"; print "Ignoring update of frozen/inactive user $user\n";
return 0; return 0;
} }
fatal("$user is not active! Cannot update the account!"); fatal("$user is not active! Cannot update the account!");
...@@ -1078,6 +1088,88 @@ sub ThawUser() ...@@ -1078,6 +1088,88 @@ sub ThawUser()
return 0; return 0;
} }
#
# Deactivate a user.
#
sub DeactivateUser()
{
#
# Only admin people can do this.
#
if (! TBAdmin($UID)) {
fatal("You do not have permission to deactivate user $user.");
}
#
# Check status.
#
if ($status ne USERSTATUS_INACTIVE) {
fatal("$user is still active! Cannot deactivate the account!")
if (!$update);
$target_user->SetStatus(USERSTATUS_INACTIVE());
$status = USERSTATUS_INACTIVE();
}
#
# Shell goes to nologin on the CONTROL node.
#
$UID = 0;
if (system("$USERMOD $user -s $NOLOGIN")) {
fatal("Could not set shell to $NOLOGIN for $user on local node.");
}
if ($CONTROL ne $BOSSNODE) {
print "Deactivating user $user ($user_number) on $CONTROL\n";
if (system("$SSH -host $CONTROL '$ACCOUNTPROXY deactivateuser $user'")){
fatal("Could not deactivate $user on $CONTROL.");
}
}
$UID = $SAVEUID;
return 0;
}
#
# Reactivate a user.
#
sub ReactivateUser()
{
#
# Only admin people can do this.
#
if (! TBAdmin($UID)) {
fatal("You do not have permission to reactivate user $user.");
}
#
# Check status.
#
if ($status ne USERSTATUS_ACTIVE) {
fatal("$user is not active! Cannot reactivate the account!")
if (!$update);
$target_user->SetStatus(USERSTATUS_ACTIVE());
$status = USERSTATUS_ACTIVE();
}
$UID = 0;
if ($CONTROL ne $BOSSNODE) {
print "Reactivating user $user ($user_number) on $CONTROL\n";
if (system("$SSH -host $CONTROL '$ACCOUNTPROXY reactivateuser $user'")){
fatal("Could not reactivate $user on $CONTROL.");
}
}
$UID = $SAVEUID;
# Similar to freeze/thaw for our purposes.
UpdateUser(0) == 0
or fatal("Cannot reactivate $user");
#
# Invoke as real user for auditing.
#
$EUID = $UID;
system("$SETGROUPS $user");
$EUID = 0;
return 0;
}
# #
# Verify a user. Converts status and sends email # Verify a user. Converts status and sends email
# #
......
...@@ -56,7 +56,7 @@ use vars qw(@ISA @EXPORT); ...@@ -56,7 +56,7 @@ use vars qw(@ISA @EXPORT);
TB_USERINFO_READINFO TB_USERINFO_MODIFYINFO TB_USERINFO_READINFO TB_USERINFO_MODIFYINFO
TB_USERINFO_MIN TB_USERINFO_MAX TB_USERINFO_MIN TB_USERINFO_MAX
USERSTATUS_ACTIVE USERSTATUS_FROZEN USERSTATUS_ACTIVE USERSTATUS_FROZEN USERSTATUS_INACTIVE
USERSTATUS_UNAPPROVED USERSTATUS_UNVERIFIED USERSTATUS_NEWUSER USERSTATUS_UNAPPROVED USERSTATUS_UNVERIFIED USERSTATUS_NEWUSER
USERSTATUS_ARCHIVED USERSTATUS_NONLOCAL USERSTATUS_ARCHIVED USERSTATUS_NONLOCAL
...@@ -310,6 +310,7 @@ sub USERSTATUS_UNVERIFIED() { "unverified"; } ...@@ -310,6 +310,7 @@ sub USERSTATUS_UNVERIFIED() { "unverified"; }
sub USERSTATUS_NEWUSER() { "newuser"; } sub USERSTATUS_NEWUSER() { "newuser"; }
sub USERSTATUS_ARCHIVED() { "archived"; } sub USERSTATUS_ARCHIVED() { "archived"; }
sub USERSTATUS_NONLOCAL() { "nonlocal"; } sub USERSTATUS_NONLOCAL() { "nonlocal"; }
sub USERSTATUS_INACTIVE() { "inactive"; }
# #
# We want valid project membership to be non-zero for easy membership # We want valid project membership to be non-zero for easy membership
......
...@@ -266,6 +266,7 @@ endif ...@@ -266,6 +266,7 @@ endif
$(INSTALL_CVSWEBCGI) $(INSTALL_CVSWEBCGI)
$(INSTALL_OPSCVSWEBCONF) $(INSTALL_OPSCVSWEBCONF)
$(INSTALL_OPSCVSWEBCGI) $(INSTALL_OPSCVSWEBCGI)
cd $(OBJDIR) && gmake install-setbuildinfo
apt-install: $(addprefix $(INSTALL_WWWDIR)/apt/, $(ALLAPTUI)) \ apt-install: $(addprefix $(INSTALL_WWWDIR)/apt/, $(ALLAPTUI)) \
$(addprefix $(INSTALL_WWWDIR)/apt/js/, $(ALLAPTJS)) \ $(addprefix $(INSTALL_WWWDIR)/apt/js/, $(ALLAPTJS)) \
......
...@@ -188,7 +188,7 @@ function Do_VerifySpeaksfor() ...@@ -188,7 +188,7 @@ function Do_VerifySpeaksfor()
global $ajax_args; global $ajax_args;
global $TBDIR, $COOKDIEDOMAIN, $TBMAINSITE, $PROTOGENI_GENIWEBLOGIN; global $TBDIR, $COOKDIEDOMAIN, $TBMAINSITE, $PROTOGENI_GENIWEBLOGIN;
global $TBAUTHCOOKIE, $TBLOGINCOOKIE, $TBAUTHTIMEOUT, $TBNAMECOOKIE; global $TBAUTHCOOKIE, $TBLOGINCOOKIE, $TBAUTHTIMEOUT, $TBNAMECOOKIE;
global $OURDOMAIN; global $OURDOMAIN, $TBMAILADDR;
$embedded = 0; $embedded = 0;
if (! ($TBMAINSITE || $PROTOGENI_GENIWEBLOGIN)) { if (! ($TBMAINSITE || $PROTOGENI_GENIWEBLOGIN)) {
...@@ -340,6 +340,13 @@ function Do_VerifySpeaksfor() ...@@ -340,6 +340,13 @@ function Do_VerifySpeaksfor()
TBDB_TRUSTSTRING_LOCALROOT); TBDB_TRUSTSTRING_LOCALROOT);
} }
} }
if ($this_user->status() == TBDB_USERSTATUS_INACTIVE) {
SPITAJAX_ERROR(1, "Your account has gone inactive. Please ".
"contact $TBMAILADDR to have your ".
"account restored.");
session_destroy();
return;
}
} }
} }
list ($loginhash, $logincrc) = list ($loginhash, $logincrc) =
......
...@@ -242,12 +242,28 @@ else { ...@@ -242,12 +242,28 @@ else {
sleep(1); sleep(1);
SPITHEADER(); SPITHEADER();
echo "<h3> echo "<h4>
Your account has been frozen due to earlier login attempt Your account has been frozen due to earlier login attempt
failures. You must contact $TBMAILADDR to have your account failures. You must contact $TBMAILADDR to have your account
restored. <br> <br> restored. <br> <br>
Please do not attempt to login again; it will not work! Please do not attempt to login again; it will not work!
</h3>\n"; </h4>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='js/lib/bootstrap.js'></script>\n";
echo "<script src='js/lib/require.js' data-main='js/main'></script>";
SPITFOOTER();
return;
}
else if ($dologin_status == DOLOGIN_STATUS_INACTIVE) {
# Short delay.
sleep(1);
SPITHEADER();
echo "<h4>
Your account has gone <b>inactive</b>. Please contact $TBMAILADDR
to have your account restored. <br> <br>
Please do not attempt to login again; it will not work!
</h4>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n"; echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='js/lib/bootstrap.js'></script>\n"; echo "<script src='js/lib/bootstrap.js'></script>\n";
echo "<script src='js/lib/require.js' data-main='js/main'></script>"; echo "<script src='js/lib/require.js' data-main='js/main'></script>";
......
...@@ -77,6 +77,7 @@ define("TBDB_USERSTATUS_UNVERIFIED", "unverified"); ...@@ -77,6 +77,7 @@ define("TBDB_USERSTATUS_UNVERIFIED", "unverified");
define("TBDB_USERSTATUS_FROZEN", "frozen"); define("TBDB_USERSTATUS_FROZEN", "frozen");
define("TBDB_USERSTATUS_ARCHIVED", "archived"); define("TBDB_USERSTATUS_ARCHIVED", "archived");
define("TBDB_USERSTATUS_NONLOCAL", "nonlocal"); define("TBDB_USERSTATUS_NONLOCAL", "nonlocal");
define("TBDB_USERSTATUS_INACTIVE", "inactive");
# #
# Type of new account. # Type of new account.
...@@ -108,7 +109,7 @@ define("TBDB_TRUSTSTRING_GROUPROOT", "group_root"); ...@@ -108,7 +109,7 @@ define("TBDB_TRUSTSTRING_GROUPROOT", "group_root");
define("TBDB_TRUSTSTRING_PROJROOT", "project_root"); define("TBDB_TRUSTSTRING_PROJROOT", "project_root");
# #
# Map to new names # Map to new names in the UI, the old ones are nonsensical.
# #
$newTrustMap = array("none" => "none", $newTrustMap = array("none" => "none",
"user" => "user", "user" => "user",
......
<?php <?php
# #
# Copyright (c) 2000-2014 University of Utah and the Flux Group. # Copyright (c) 2000-2014, 2016 University of Utah and the Flux Group.
# #
# {{{EMULAB-LICENSE # {{{EMULAB-LICENSE
# #
...@@ -252,12 +252,25 @@ else { ...@@ -252,12 +252,25 @@ else {
sleep(1); sleep(1);
PAGEHEADER("Login", $view); PAGEHEADER("Login", $view);
echo "<h3> echo "<h4>
Your account has been frozen due to earlier login attempt Your account has been frozen due to earlier login attempt
failures. You must contact $TBMAILADDR to have your account failures. You must contact $TBMAILADDR to have your account
restored. <br> <br> restored. <br> <br>
Please do not attempt to login again; it will not work! Please do not attempt to login again; it will not work!
</h3>\n"; </h4>\n";
PAGEFOOTER($view);
die("");
}
else if ($dologin_status == DOLOGIN_STATUS_INACTIVE) {
# Short delay.
sleep(1);
PAGEHEADER("Login", $view);
echo "<h4>
Your account has gone <b>inactive</b>. Please contact $TBMAILADDR
to have your account restored. <br> <br>
Please do not attempt to login again; it will not work!
</h4>\n";
PAGEFOOTER($view); PAGEFOOTER($view);
die(""); die("");
} }
......
...@@ -69,6 +69,7 @@ define("CHECKLOGIN_WIKIONLY", 0x0200000); ...@@ -69,6 +69,7 @@ define("CHECKLOGIN_WIKIONLY", 0x0200000);
define("CHECKLOGIN_OPSGUY", 0x0400000); # Member of emulab-ops. define("CHECKLOGIN_OPSGUY", 0x0400000); # Member of emulab-ops.
define("CHECKLOGIN_ISFOREIGN_ADMIN", 0x0800000); # Admin of another Emulab. define("CHECKLOGIN_ISFOREIGN_ADMIN", 0x0800000); # Admin of another Emulab.
define("CHECKLOGIN_NONLOCAL", 0x1000000); define("CHECKLOGIN_NONLOCAL", 0x1000000);
define("CHECKLOGIN_INACTIVE", 0x2000000);
# #
# Constants for tracking possible login attacks. # Constants for tracking possible login attacks.
...@@ -82,6 +83,7 @@ define("DOLOGIN_STATUS_OKAY", 0); ...@@ -82,6 +83,7 @@ define("DOLOGIN_STATUS_OKAY", 0);
define("DOLOGIN_STATUS_ERROR", -1); define("DOLOGIN_STATUS_ERROR", -1);
define("DOLOGIN_STATUS_IPFREEZE", -2); define("DOLOGIN_STATUS_IPFREEZE", -2);
define("DOLOGIN_STATUS_WEBFREEZE", -3); define("DOLOGIN_STATUS_WEBFREEZE", -3);
define("DOLOGIN_STATUS_INACTIVE", -4);
# So we can redefine this in the APT pages. # So we can redefine this in the APT pages.
$CHANGEPSWD_PAGE = "moduserinfo.php3"; $CHANGEPSWD_PAGE = "moduserinfo.php3";
...@@ -448,6 +450,8 @@ function LoginStatus() { ...@@ -448,6 +450,8 @@ function LoginStatus() {
$CHECKLOGIN_STATUS |= CHECKLOGIN_UNVERIFIED; $CHECKLOGIN_STATUS |= CHECKLOGIN_UNVERIFIED;
if (strcmp($status, TBDB_USERSTATUS_ACTIVE) == 0) if (strcmp($status, TBDB_USERSTATUS_ACTIVE) == 0)
$CHECKLOGIN_STATUS |= CHECKLOGIN_ACTIVE; $CHECKLOGIN_STATUS |= CHECKLOGIN_ACTIVE;
if (strcmp($status, TBDB_USERSTATUS_INACTIVE) == 0)
$CHECKLOGIN_STATUS |= CHECKLOGIN_INACTIVE;
if (isset($wikiname) && $wikiname != "") if (isset($wikiname) && $wikiname != "")
$CHECKLOGIN_WIKINAME = $wikiname; $CHECKLOGIN_WIKINAME = $wikiname;
if ($opsguy) if ($opsguy)
...@@ -572,7 +576,7 @@ function LOGGEDINORDIE($uid, $modifier = 0, $login_url = NULL) { ...@@ -572,7 +576,7 @@ function LOGGEDINORDIE($uid, $modifier = 0, $login_url = NULL) {
# #
function CheckLoginConditions($status) function CheckLoginConditions($status)
{ {
global $CHANGEPSWD_PAGE; global $CHANGEPSWD_PAGE, $TBMAILADDR;
if ($status & CHECKLOGIN_PSWDEXPIRED) if ($status & CHECKLOGIN_PSWDEXPIRED)
USERERROR("Your password has expired. ". USERERROR("Your password has expired. ".
...@@ -581,6 +585,10 @@ function CheckLoginConditions($status) ...@@ -581,6 +585,10 @@ function CheckLoginConditions($status)
if ($status & CHECKLOGIN_FROZEN) if ($status & CHECKLOGIN_FROZEN)
USERERROR("Your account has been frozen!", USERERROR("Your account has been frozen!",
1, HTTP_403_FORBIDDEN); 1, HTTP_403_FORBIDDEN);
if ($status & CHECKLOGIN_INACTIVE)
USERERROR("Your account has gone inactive. ".
"Please contact $TBMAILADDR to restore it.",
1, HTTP_403_FORBIDDEN);
if ($status & (CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER)) if ($status & (CHECKLOGIN_UNVERIFIED|CHECKLOGIN_NEWUSER))
USERERROR("You have not verified your account yet!", USERERROR("You have not verified your account yet!",
1, HTTP_403_FORBIDDEN); 1, HTTP_403_FORBIDDEN);
...@@ -883,6 +891,10 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) { ...@@ -883,6 +891,10 @@ function DOLOGIN($token, $password, $adminmode = 0, $nopassword = 0) {
$user->UpdateWebLoginFail(); $user->UpdateWebLoginFail();
return DOLOGIN_STATUS_WEBFREEZE; return DOLOGIN_STATUS_WEBFREEZE;
} }
# inactive users need special handling for now.
if ($user->status() == TBDB_USERSTATUS_INACTIVE) {
return DOLOGIN_STATUS_INACTIVE;
}
if (!$nopassword) { if (!$nopassword) {
$encoding = crypt("$password", $db_encoding); $encoding = crypt("$password", $db_encoding);
......
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