All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

changeuid.in 4.99 KB
Newer Older
1
#!/usr/bin/perl -wT
2
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
3
# Copyright (c) 2004, 2006, 2007, 2008 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
#
use English;
use Getopt::Std;

#
# Change the uid of an UNAPPROVED user. 
#
sub usage()
{
    print(STDERR "Usage: changeuid <olduid> <newuid>\n");
    exit(-1);
}
my $optlist = "df";
my $debug   = 0;
my $force   = 0;

#
# Configure variables
#
my $TB		= "@prefix@";

#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libaudit;
use libdb;
use libtestbed;
51 52 53 54
use User;

# Protos.
sub fatal($);
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

#
# Turn off line buffering on output
#
$| = 1;

#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
#
if ($UID == 0) {
    die("*** $0:\n".
	"    Please do not run this as root! Its already setuid!\n");
}

# Only admin types!
77
if (!TBAdmin()) {
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    die("*** $0:\n".
	"    Only TB administrators can run this script!\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 (defined($options{"d"})) {
    $debug = 1;
}
if (defined($options{"f"})) {
    $force = 1;
}
if (@ARGV != 2) {
    usage();
}
my $olduid = shift(@ARGV);
my $newuid = shift(@ARGV);

102 103 104 105 106 107 108 109 110
#
# Make sure that the new uid is valid!
#
if (! TBcheck_dbslot($newuid, "users", "uid",
		     TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
    die("*** $0:\n".
	"    Invalid characters in new uid: $newuid!\n");
}

111 112 113 114 115 116 117 118 119 120
#
# This script is always audited. Mail is sent automatically upon exit.
#
if (AuditStart(0)) {
    #
    # Parent exits normally
    #
    exit(0);
}

121 122 123 124 125
# Map target user to object.
my $target_user = User->Lookup($olduid);
if (! defined($target_user)) {
    fatal("$olduid does not exist!");
}
126

127 128 129 130
# Map invoking user to object.
my $this_user = User->LookupByUnixId($UID);
if (! defined($this_user)) {
    fatal("You ($UID) do not exist!");
131
}
132
$target_dbid  = $target_user->dbid();
133 134 135 136 137 138

#
# Only operate on unapproved users (must be verified). Any other state
# is hard to deal with cause of exported homedirs, existing experiments,
# files that need to be changed on disk, etc. Maybe add this support later.
# 
139 140
if ($target_user->status() ne USERSTATUS_UNAPPROVED()) {
    fatal("User '$olduid' must be an unapproved (verified) user!");
141 142 143 144 145 146
}

#
# Obviously the new user must not exist in the users table. This is the
# last table we change below ...
#
147 148 149
my $new_user = User->Lookup($newuid);
if (defined($new_user)) {
    fatal("User '$newuid' is already in the DB!");
150 151 152 153 154 155 156
}

#
# Change a bunch of tables!
#
print "Updating group_membership table ...\n";
DBQueryFatal("update group_membership set uid='$newuid' ".
157
	     "where uid_idx='$target_dbid'");
158 159 160

print "Updating projects table ...\n";
DBQueryFatal("update projects set head_uid='$newuid' ".
161
	     "where head_idx='$target_dbid'");
162 163 164

print "Updating user_pubkeys table ...\n";
DBQueryFatal("update user_pubkeys set uid='$newuid' ".
165
	     "where uid_idx='$target_dbid'");
166 167 168

print "Updating user_sfskeys table ...\n";
DBQueryFatal("update user_sfskeys set uid='$newuid' ".
169
	     "where uid_idx='$target_dbid'");
170 171 172

print "Updating user_stats table ...\n";
DBQueryFatal("update user_stats set uid='$newuid' ".
173 174 175 176 177
	     "where uid_idx='$target_dbid'");

print "Updating user_sslcerts table ...\n";
DBQueryFatal("update user_sslcerts set uid='$newuid' ".
	     "where uid_idx='$target_dbid'");
178 179 180 181 182

print "Updating widearea_accounts table ...\n";
DBQueryFatal("update widearea_accounts set uid='$newuid' ".
	     "where uid='$olduid'");

183 184
print "Updating groups table ...\n";
DBQueryFatal("update groups set leader='$newuid' ".
185
	     "where leader_idx='$target_dbid'");
186

187 188
# Auto logout old user. 
print "Clearing logins table ...\n";
189
DBQueryFatal("delete from login where uid_idx='$target_dbid'");
190 191 192 193 194 195 196 197

#
# Lastly change users table; if anything breaks above we can still run
# this script to finish the job. Technically, we should lock these tables
# so that no one can sneak in and create a new user with the same uid
# as new one, but that is not likely to happen!
#
print "Updating users table ...\n";
198
DBQueryFatal("update users set uid='$newuid' where uid_idx='$target_dbid'");
199 200 201

exit(0);

202 203 204 205 206 207
sub fatal($) {
    my($mesg) = $_[0];

    die("*** $0:\n".
	"    $mesg\n");
}