Commit da45fee0 authored by Leigh Stoller's avatar Leigh Stoller

Remove a bunch of queries on the users table, switching to user object

methods.

Change a bunch of queries that join on the users table to use the idx
instead of the uid. This will need to be completed before we can really
archive users away, but close at this point.
parent a757ff14
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006 University of Utah and the Flux Group.
# Copyright (c) 2005, 2006, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -50,6 +50,7 @@ sub fatal($);
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -105,15 +106,14 @@ else {
die("Bad data in uid: $uid");
}
# Need the password hash ...
$query_result =
DBQueryFatal("select u.usr_pswd from users as u ".
"where u.uid='$uid'");
if ($query_result->numrows == 0) {
fatal("No such user $uid!");
# Map target user to object.
my $target_user = User->Lookup($uid);
if (! defined($target_user)) {
fatal("$uid does not exist!");
}
my ($passhash) = $query_result->fetchrow_array();
# Need the password hash ...
my $passhash = $target_user->pswd();
# shell escape.
$passhash =~ s/\$/\\\$/g;
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006 University of Utah and the Flux Group.
# Copyright (c) 2005, 2006, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -50,6 +50,7 @@ sub fatal($);
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -102,6 +103,13 @@ else {
die("Bad data in user: $user.");
}
# Map target user to object.
my $target_user = User->Lookup($user);
if (! defined($target_user)) {
fatal("$user does not exist!");
}
my $user_dbid = $target_user->dbid();
#
# This script always does the right thing, so no permission checks.
# In fact, all it does is call over to ops to run a script over there.
......@@ -113,7 +121,8 @@ else {
my $query_result =
DBQueryFatal("select p.pid,p.trust from group_membership as p ".
"left join groups as g on g.pid=p.pid and g.gid=p.gid ".
"where uid='$user' and p.pid=g.gid and trust!='none'");
"where uid_idx='$user_dbid' and p.pid=g.gid and ".
" trust!='none'");
while (my ($pid,$trust) = $query_result->fetchrow_array()) {
#
......@@ -136,10 +145,8 @@ exit(0)
# report bugs about Emulab!
#
# Admin users ... TBAdmin() test does not work for this test ...
$query_result =
DBQueryFatal("select admin from users where uid='$user'");
my ($isadmin) = $query_result->fetchrow_array();
if ($isadmin) {
#
if ($target_user->admin()) {
push(@glist, "Emulab/admin");
}
else {
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# Copyright (c) 2005, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -47,6 +47,7 @@ $| = 1;
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -105,20 +106,11 @@ else {
# Note that adduser will just update the password if the user already
# exist in the wiki.
#
#
# Look in the DB to see if there is already a wikiname defined. If
# we use that. Otherwise have to form one from the user name. Ick.
#
my $query_result =
DBQueryFatal("select mailman_password ".
"from users where uid='$user'");
if (!$query_result->numrows) {
fatal("No such user $user in the DB!");
my $target_user = User->Lookup($user);
if (! defined($target_user)) {
fatal("$user does not exist!");
}
my ($password) = $query_result->fetchrow_array();
my $password = $target_user->mailman_password();
if (!defined($password)) {
fatal("No password defined for $user!");
}
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# Copyright (c) 2005, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -54,6 +54,7 @@ $| = 1;
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -80,14 +81,6 @@ if (! $MAILMANSUPPORT) {
exit(0);
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
......@@ -114,15 +107,13 @@ else {
die("Bad data in uid: $target_uid");
}
my $query_result =
DBQueryFatal("select usr_email, mailman_password, usr_name ".
"from users where uid='$target_uid'");
fatal("No such user in DB: $target_uid!")
if (!$query_result->numrows);
my ($email, $password, $fullname) = $query_result->fetchrow_array();
my $target_user = User->Lookup($target_uid);
if (! defined($target_user)) {
fatal("$target_uid does not exist!");
}
my $email = $target_user->email();
my $password = $target_user->mailman_password();
my $fullname = $target_user->name();
#
# Note that since we are sending cleartext passwords over, pipe the info
......@@ -141,6 +132,9 @@ if ($CONTROL ne $BOSSNODE) {
TBScriptLock("mailman_update") == 0 or
fatal("Could not get the lock!");
# Watch for embedded quotes.
$fullname =~ s/(\')/\'\\'\'/g;
system("echo \"$password \'$fullname\'\" | ".
"$SSH -host $CONTROL $MMPROXY $optarg adduser $target_uid $email");
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# Copyright (c) 2005, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -54,6 +54,7 @@ $| = 1;
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -80,14 +81,6 @@ if (! $MAILMANSUPPORT) {
exit(0);
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
......@@ -114,18 +107,12 @@ else {
die("Bad data in uid: $target_uid");
}
my $query_result =
DBQueryFatal("select usr_email, mailman_password, usr_name ".
"from users where uid='$target_uid'");
fatal("No such user in DB: $target_uid!")
if (!$query_result->numrows);
my ($email, $password, $fullname) = $query_result->fetchrow_array();
my $target_user = User->Lookup($target_uid);
if (! defined($target_user)) {
fatal("$target_uid does not exist!");
}
my $email = $target_user->email();
#
# Note that since we are sending cleartext passwords over, pipe the info
# into its STDIN so that the passwords are not visible in a ps listing.
#
# For ssh.
#
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005 University of Utah and the Flux Group.
# Copyright (c) 2005, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -53,6 +53,7 @@ $| = 1;
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -79,14 +80,6 @@ if (! $MAILMANSUPPORT) {
exit(0);
}
#
# Get user DB uid.
#
if (! UNIX2DBUID($UID, \$dbuid)) {
die("*** $0:\n".
" You do not exist in the Emulab Database!\n");
}
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
......@@ -113,14 +106,13 @@ else {
die("Bad data in uid: $target_uid");
}
my $query_result =
DBQueryFatal("select usr_email, mailman_password, usr_name ".
"from users where uid='$target_uid'");
fatal("No such user in DB: $target_uid!")
if (!$query_result->numrows);
my ($email, $password, $fullname) = $query_result->fetchrow_array();
my $target_user = User->Lookup($target_uid);
if (! defined($target_user)) {
fatal("$target_uid does not exist!");
}
my $email = $target_user->email();
my $password = $target_user->mailman_password();
my $fullname = $target_user->name();
#
# Note that since we are sending cleartext passwords over, pipe the info
......@@ -139,6 +131,9 @@ if ($CONTROL ne $BOSSNODE) {
TBScriptLock("mailman_update") == 0 or
fatal("Could not get the lock!");
# Watch for embedded quotes.
$fullname =~ s/(\')/\'\\'\'/g;
system("echo \"$password \'$fullname\'\" | ".
" $SSH -host $CONTROL $MMPROXY ".
" $optarg modifymember $target_uid $email");
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006 University of Utah and the Flux Group.
# Copyright (c) 2005, 2006, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -52,6 +52,7 @@ $| = 1;
use lib "@prefix@/lib";
use libdb;
use libtestbed;
use User;
#
# If no bugdb support, just exit.
......@@ -89,7 +90,8 @@ my $optarg = ($debug ? "-d" : "");
# Initialize a mailman password for all users.
#
my $query_result =
DBQueryFatal("select uid from users where mailman_password is NULL");
DBQueryFatal("select uid from users ".
"where mailman_password is NULL and status!='archived'");
while (my ($uid) = $query_result->fetchrow_array()) {
print "Setting initial mailman password for $uid\n"
......
......@@ -78,6 +78,7 @@ sub mysystem($)
sub Lookup($$)
{
my ($class, $token) = @_;
my $status_archived = $USERSTATUS_ARCHIVED;
my $query_result;
# Look in cache first
......@@ -88,13 +89,18 @@ sub Lookup($$)
# For backwards compatability, look to see if the token is numeric
# or alphanumeric. If numeric, assumes its an idx, otherwise a name.
#
if ($token =~ /^\d*$/) {
if ($token =~ /^\d+$/) {
$query_result =
DBQueryWarn("select * from users where uid_idx='$token'");
}
elsif ($token =~ /^\w*$/) {
elsif ($token =~ /^\w+$/) {
# When looking up by uid, only look for non-archived users;
# Must use an idx if you really want an archived user. This
# will prevent problems with code that has not yet been
# changed to use the idx field.
$query_result =
DBQueryWarn("select * from users where uid='$token'");
DBQueryWarn("select * from users ".
"where uid='$token' and status!='$status_archived'");
}
else {
return undef;
......@@ -208,10 +214,12 @@ sub LookupByUnixId($$)
sub LookupByWikiName($$)
{
my ($class, $wikiname) = @_;
my $status_archived = $USERSTATUS_ARCHIVED;
my $query_result =
DBQueryFatal("select uid_idx from users ".
"where wikiname='$wikiname'");
"where wikiname='$wikiname' and ".
" status!='$status_archived'");
return undef
if (! $query_result || !$query_result->numrows);
......@@ -228,10 +236,12 @@ sub LookupByWikiName($$)
sub LookupByEmail($$)
{
my ($class, $email) = @_;
my $status_archived = $USERSTATUS_ARCHIVED;
my $query_result =
DBQueryFatal("select uid_idx from users ".
"where LCASE(usr_email)=LCASE('$email')");
"where LCASE(usr_email)=LCASE('$email') and ".
" status!='$status_archived'");
return undef
if (! $query_result || !$query_result->numrows);
......@@ -440,6 +450,18 @@ sub ThisUser($)
return User->LookupByUnixId($UID);
}
#
# The "implied" user is the user the web interface says we are running as.
#
sub ImpliedUser($)
{
return undef
if (! exists($ENV{'HTTP_INVOKING_USER'}));
# The lookup routine checks it argument, so no need to taint check.
return User->Lookup($ENV{'HTTP_INVOKING_USER'});
}
#
# Refresh a class instance by reloading from the DB.
#
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2004, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -99,7 +99,7 @@ mysystem("$TB/sbin/mkproj $pid");
#
my $users_result =
DBQueryFatal("select distinct u.uid,u.admin from group_membership as m ".
"left join users as u on u.uid=m.uid ".
"left join users as u on u.uid_idx=m.uid_idx ".
"where u.status='" . USERSTATUS_ACTIVE() . "'");
while (my ($uid,$admin) = $users_result->fetchrow_array()) {
next
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# All rights reserved.
#
use Fcntl ':flock';
......@@ -73,6 +73,7 @@ use lib "@prefix@/lib";
use libdb;
use libtestbed;
use libtblog;
use User;
#
# We don't want to run this script unless its the real version.
......@@ -300,7 +301,7 @@ sub ActiveUsers()
DBQuery("SELECT DISTINCT u.usr_email from experiments as e ".
"left join group_membership as p ".
" on e.pid=p.pid and p.pid=p.gid ".
"left join users as u on u.uid=p.uid ".
"left join users as u on u.uid_idx=p.uid_idx ".
"where u.status='active' and ".
" e.state='active' ".
"order by u.usr_email"))) {
......@@ -325,7 +326,7 @@ sub RecentUsers()
if (! ($query_result =
DBQuery("select distinct u.usr_email from user_stats as s ".
"left join users as u on u.uid=s.uid ".
"left join users as u on u.uid_idx=s.uid_idx ".
"where ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(s.last_activity)) <= $limit) ".
"order by u.usr_email"))) {
......@@ -352,7 +353,7 @@ sub RecentProjects()
DBQuery("select distinct u.usr_email from project_stats as s ".
"left join group_membership as g on ".
" g.pid=s.pid and g.gid=g.pid ".
"left join users as u on u.uid=g.uid ".
"left join users as u on u.uid_idx=g.uid_idx ".
"where u.status='active' and ".
" ((UNIX_TIMESTAMP(now()) - ".
" UNIX_TIMESTAMP(s.last_activity)) <= $limit) ".
......@@ -379,7 +380,7 @@ sub RecentProjectLeaders()
DBQuery("select distinct u.usr_email from project_stats as s ".
"left join group_membership as g on ".
" g.pid=s.pid and g.gid=g.pid ".
"left join users as u on u.uid=g.uid ".
"left join users as u on u.uid_idx=g.uid_idx ".
"left join projects as p on u.uid=p.head_uid ".
"where u.status='active' and ".
" ((UNIX_TIMESTAMP(now()) - ".
......@@ -424,7 +425,7 @@ sub WideAreaPeople()
my $query_result =
DBQueryFatal("SELECT DISTINCT u.usr_email from projects as p ".
"left join group_membership as m on m.pid=p.pid ".
"left join users as u on u.uid=m.uid ".
"left join users as u on u.uid_idx=m.uid_idx ".
"where p.approved!=0 and p.pcremote_ok is not null ".
" and m.trust!='none' and u.status='active' ".
"order by usr_email");
......@@ -442,7 +443,7 @@ sub ProjectLeaders()
($MAILMANSUPPORT ?
", u.uid ,u.usr_name, u.mailman_password " : "") .
" from projects as p ".
"left join users as u on u.uid=p.head_uid ".
"left join users as u on u.uid_idx=p.head_idx ".
"where p.approved!=0 ".
"order by usr_email");
......
......@@ -499,6 +499,7 @@ sub USERSTATUS_FROZEN() { "frozen"; }
sub USERSTATUS_UNAPPROVED() { "unapproved"; }
sub USERSTATUS_UNVERIFIED() { "unverified"; }
sub USERSTATUS_NEWUSER() { "newuser"; }
sub USERSTATUS_ARCHIVED() { "archived"; }
#
# We want valid project membership to be non-zero for easy membership
......@@ -911,19 +912,26 @@ sub TBGrpTrust($$$)
$gid = $pid;
}
#
# Must map to an existing user to be trusted, obviously
#
my $target_user = User->Lookup($uid);
return PROJMEMBERTRUST_NONE
if (! defined($target_user));
my $uid_idx = $target_user->uid_idx();
#
# User must be active to be trusted.
#
my $query_result =
DBQueryFatal("select status from users ".
"where uid='$uid' and status='" . USERSTATUS_ACTIVE() . "'");
if ($query_result->numrows == 0) {
return PROJMEMBERTRUST_NONE;
}
return PROJMEMBERTRUST_NONE
if ($target_user->status() ne USERSTATUS_ACTIVE());
#
# Must be a member of the group.
#
$query_result =
DBQueryFatal("select trust from group_membership ".
"where uid='$uid' and pid='$pid' and gid='$gid'");
"where uid_idx='$uid_idx' and pid='$pid' and gid='$gid'");
#
# No membership is the same as no trust. True? Maybe an error instead?
......@@ -954,20 +962,15 @@ sub TBProjTrust($$)
}
#
# Test admin status. Optional argument is the UID or Name to test. If not
# provided, then test the current UID.
#
# XXX Argument is *either* a numeric UID, or a string name.
# Test admin status. Ignore argument; we only care if the current user
# has admin privs turned on.
#
# usage: TBAdmin([int or char* uid]);
# usage: TBAdmin();
# returns 1 if an admin type.
# returns 0 if a mere user.
#
sub TBAdmin(;$)
{
my($uid) = @_;
my($name);
#
# No one is considered an admin unless they have the magic environment
# variable set (so that you have to be a bit more explict about wanting
......@@ -979,54 +982,27 @@ sub TBAdmin(;$)
return 0;
}
if (!defined($uid)) {
$uid = $UID;
}
#
# Test if numeric. Map to name if it is.
#
if ($uid =~ /^[0-9]+$/) {
($name) = getpwuid($uid)
or die "$uid not in passwd file\n";
}
else {
$name = $uid;
}
my $query_result =
DBQueryFatal("select admin from users where uid='$name'");
# Map current user to object and confirm admin status from db.
my $this_user = User->ThisUser();
return 0
if (! defined($this_user));
my @row = $query_result->fetchrow_array();
if ($row[0] == 1) {
return 1;
}
return 0;
return $this_user->admin();
}
#
# Test whether current user is a member of the emulab-ops project.
# We ignore the argument; always test the current user.
#
sub TBOpsGuy(;$)
{
my($uid) = @_;
my($name);
if (!defined($uid)) {
$uid = $UID;
}
# Map current user to object and confirm admin status from db.
my $this_user = User->ThisUser();
return 0
if (! defined($this_user));
#
# Test if numeric. Map to name if it is.
#
if ($uid =~ /^[0-9]+$/) {
($name) = getpwuid($uid)
or die "$uid not in passwd file\n";
}
else {
$name = $uid;
}
return TBMinTrust(TBProjTrust($name, $TBOPSPID), PROJMEMBERTRUST_USER());
return TBMinTrust(TBProjTrust($this_user->uid_idx(), $TBOPSPID),
PROJMEMBERTRUST_USER());
}
#
......@@ -1495,7 +1471,7 @@ sub TBLeaderMailList($;$) {
# have the strings in variables...
my $query_result =
DBQueryFatal("select distinct usr_name,u.uid,usr_email from users as u ".
"left join group_membership as gm on gm.uid=u.uid ".
"left join group_membership as gm on gm.uid_idx=u.uid_idx ".
"where (trust='project_root' and pid='$pid') or ".
"(trust='group_root' and pid='$pid' and gid='$gid') ".
"order by trust DESC, usr_name");
......@@ -2477,20 +2453,16 @@ sub TBImageLoadMaxOkay($$;@)
# returns 1 if the UID is okay.
# returns 0 if the UID is bogus.
#
sub UserDBInfo ($$$) {
my($dbuid, $username, $useremail) = @_;
my $query_result =
DBQueryWarn("select usr_name,usr_email from users ".
"where uid='$dbuid'");
if (!$query_result || $query_result->num_rows < 1) {
return 0;
}
sub UserDBInfo($$$)
{
my ($dbuid, $username, $useremail) = @_;
my @row = $query_result->fetchrow_array();
$$username = $row[0];
$$useremail = $row[1];
my $target_user = User->Lookup($dbuid);
return 0
if (! defined($target_user));
$$username = $target_user->name();
$$useremail = $target_user->email();
return 1;
}
......@@ -2544,10 +2516,7 @@ sub TBUnixGroupList ($) {
}
#
# Map UID to DB UID (login). Does a DB check to make sure user is known to
# the DB (user obviously has a regular account), and that account will
# always match what the DB says. Redundant, I know. But consider it a
# sanity (or consistency) check.
# Map UID to DB UID (login). This function will eventually be tossed.
#
# usage: UNIX2DBUID(int uid, \$login)
# returns 1 if the UID is okay.
......@@ -2556,23 +2525,11 @@ sub TBUnixGroupList ($) {
sub UNIX2DBUID ($$) {
my($unix_uid, $userlogin) = @_;
my $query_result =
DBQueryFatal("select uid from users where unix_uid='$unix_uid'");
if ($query_result->num_rows < 1) {
return 0;
}
my @row = $query_result->fetchrow_array();
my ($pwname) = getpwuid($unix_uid) or
die("*** $unix_uid is not in the password file!");
if ($row[0] ne $pwname) {
warn("*** WARNING: $pwname does not match $row[0]\n");
return 0;
}
my $target_user = User->LookupByUnixId($unix_uid);
return 0
if (! defined($target_user));
$$userlogin = $row[0];
$$userlogin = $target_user->uid();
return 1;
}
......@@ -4160,9 +4117,10 @@ sub TBNodeUpdateAccountsByUID($)
my $query_result =
DBQueryFatal("select p.pid,pcremote_ok from users as u ".
"left join group_membership as g on ".
" u.uid=g.uid and g.pid=g.gid ".
" u.uid_idx=g.uid_idx and g.pid=g.gid ".
"left join projects as p on p.pid=g.pid ".
"where u.uid='$uid' and p.pid is not null");
"where u.uid='$uid' and u.status='active' and ".
" p.pid is not null");
while (my %row = $query_result->fetchhash()) {
my $pid = $row{'pid'};
......
......@@ -318,7 +318,7 @@ def TBMapUIDtoIDX(uid):
uid = DBQuoteSpecial(uid)
qres = DBQueryFatal("select uid_idx from users "
"where uid=%s", (uid,))
"where uid=%s and status!='archived'", (uid,))
if len(qres) == 0:
return 0
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2003, 2007 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -103,16 +103,7 @@ if ($setlogin) {
#
# Find all non admins and log them out.
#
my $query_result =
DBQueryFatal("select users.uid from login ".
"left join users on login.uid=users.uid ".
"where users.admin=0");
while (my @row = $query_result->fetchrow_array()) {
my $uid = $row[0];
DBQueryFatal("delete from login where uid='$uid'");
}
DBQueryFatal("delete from login where adminon=0'");
}
}
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006 University of Utah and the Flux Group.