Commit d0cfcfc2 authored by Leigh Stoller's avatar Leigh Stoller

Changes to allow passing password hash from the portal master

to the portal peers.

Also add locking between the portal daemon and manageremote.
parent 80b9a586
#!/usr/bin/perl -w
#
# Copyright (c) 2010-2011 University of Utah and the Flux Group.
# Copyright (c) 2010-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -121,7 +121,7 @@ sub DumpUser($)
"optional" => 0 },
"email" => {"tag" => "email",
"optional" => 0 },
"pswd" => {"tag" => "password",
"pswd" => {"tag" => "passhash",
"optional" => 0 },
"uid" => {"tag" => "uid",
"optional" => 0 },
......
......@@ -49,10 +49,12 @@ sub usage()
print " manageremote addgroup <remote> <gid>\n";
exit(1);
}
my $optlist = "dnf";
my $optlist = "dnfp";
my $debug = 0;
my $force = 0;
my $impotent = 0;
my $locked = 0;
my $fromdaemon = 0;
#
# Function prototypes
......@@ -121,8 +123,11 @@ if (defined($options{"f"})) {
if (defined($options{"n"})) {
$impotent = 1;
}
if (defined($options{"p"})) {
$fromdaemon = 1;
}
usage()
if (@ARGV < 2 || @ARGV > 4);
if (@ARGV < 2 || @ARGV > 5);
my $cmd = shift(@ARGV);
my $peername = shift(@ARGV);
......@@ -170,26 +175,36 @@ my $credential = GeniCredential->GetSelfCredential($me);
if (!defined($credential)) {
fatal("Could not create self credential for $me");
}
my $authority;
#
# All operations other then AddPeer require that the peer be
# in the DB.
#
if ($cmd eq "addpeer") {
AddPeer();
exit(0);
}
else {
if ($cmd ne "addpeer") {
my $query_result =
DBQueryFatal("select name,urn from emulab_peers ".
"where name='$peername' or urn='$peername'");
fatal("Unknown peer")
if (!$query_result->numrows);
($peername,$peerurn) = $query_result->fetchrow_array();
$authority = GeniAuthority->CreateFromRegistry("sa", $peerurn);
if (!defined($authority)) {
fatal("Could not locate authority for $peername");
}
}
my $authority = GeniAuthority->CreateFromRegistry("sa", $peerurn);
if (!defined($authority)) {
fatal("Could not locate authority for $peername");
#
# All operations other then xlogin require locking to avoid a
# race with the portal_daemon.
#
if ($cmd ne "xlogin" && !$fromdaemon) {
while (TBScriptLock("portal_op", 0, 5) != TBSCRIPTLOCK_OKAY()) {
print "Could not get the lock; trying again ... ^C to stop trying.\n";
next;
}
$locked = 1;
}
#
......@@ -204,6 +219,10 @@ SWITCH: for ($cmd) {
AddUser();
last SWITCH;
};
/^addpeer$/ && do {
AddPeer();
last SWITCH;
};
/^deluser$/ && do {
DeleteUser();
last SWITCH;
......@@ -230,8 +249,12 @@ SWITCH: for ($cmd) {
};
# Default
TBScriptUnlock()
if ($locked);
usage();
}
TBScriptUnlock()
if ($locked);
exit(0);
#
......@@ -315,7 +338,7 @@ sub AddUser(;$)
}
my $urn = GeniHRN::Generate($OURDOMAIN, "user", $user->uid());
my $xmlgoo = emutil::ExecQuiet("$DUMPUSER -p $uid");
my $xmlgoo = emutil::ExecQuiet("$DUMPUSER $uid");
if ($?) {
fatal("$DUMPUSER failed");
}
......@@ -393,7 +416,7 @@ sub ModifyUser()
}
my $urn = GeniHRN::Generate($OURDOMAIN, "user", $user->uid());
my $xmlgoo = emutil::ExecQuiet("$DUMPUSER -p $uid");
my $xmlgoo = emutil::ExecQuiet("$DUMPUSER $uid");
if ($?) {
fatal("$DUMPUSER failed");
}
......@@ -568,9 +591,7 @@ sub AddProject()
" exported=now(), updated=now(), ".
" peer='$peername'");
if (!$leader_result->numrows) {
SetGroups($leader_idx);
}
SetGroups($leader_idx);
return 0;
}
......
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -35,11 +35,12 @@ sub usage()
print("Usage: newuser [-s] -t <type> <xmlfile>\n");
exit(-1);
}
my $optlist = "dt:ns";
my $optlist = "dt:nsp";
my $debug = 0;
my $impotent= 0;
my $type = "";
my $silent = 0;
my $portal = 0;
my @keyfiles = ();
#
......@@ -213,6 +214,11 @@ foreach my $key (keys(%required)) {
fatal("Missing required attribute '$key'")
if (! exists($xmlparse->{'attribute'}->{"$key"}));
}
#
# Always delete this. Used by the portal code but we ignore it.
#
delete($xmlparse->{'attribute'}->{"passhash"})
if (exists($xmlparse->{'attribute'}->{"passhash"}));
#
# We build up an array of arguments to pass to User->Create() as we check
......
......@@ -735,6 +735,9 @@ sub UpdatePassword()
#
return 0
if (getpwuid($UID) eq "nobody");
return 0
if ($isnonlocal || $nocollabtools);
$EUID = $UID;
# And the wiki if enabled.
......@@ -882,6 +885,9 @@ sub UpdateUser(;$)
}
$UID = $SAVEUID;
return 0
if ($isnonlocal || $nocollabtools);
$EUID = $UID;
# Update elists in case email changed.
system("$MMMODIFYUSER $user")
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -183,6 +183,8 @@ my %xmlfields =
"user_interface" => ["user_interface", $SLOT_OPTIONAL],
"pubkeys" => ["pubkeys", $SLOT_SKIP],
"wikiname" => ["pubkeys", $SLOT_SKIP],
# The portal code sets this, we ignore it here.
"passhash" => ["passhash", $SLOT_SKIP],
# These are alternates.
"name" => ["usr_name", $SLOT_OPTIONAL],
"title" => ["usr_title", $SLOT_OPTIONAL],
......
......@@ -69,6 +69,7 @@ my $PGENIDOMAIN = "@PROTOGENI_DOMAIN@";
my $ELABINELAB = "@ELABINELAB@";
my $NEWUSER = "$TB/sbin/newuser";
my $RMUSER = "$TB/sbin/rmuser";
my $CHPASS = "$TB/sbin/tbacct passwd";
my $ADDUSER = "$TB/sbin/tbacct add";
my $MODUSER = "$TB/bin/moduserinfo";
my $NEWPROJ = "$TB/sbin/newproj";
......@@ -100,6 +101,7 @@ sub AddUser($)
my $credentials = $argref->{'credentials'};
my $xmlgoo = $argref->{'xmlstring'};
my $urn = $argref->{'urn'};
my $passhash;
if (! (defined($credentials) && defined($xmlgoo) && defined($urn))) {
return GeniResponse->MalformedArgsResponse("Missing arguments");
......@@ -135,6 +137,15 @@ sub AddUser($)
return GeniResponse->Create(GENIRESPONSE_BADARGS)
if (! User->ValidUID($login));
if (exists($xmlparse->{'attribute'}->{"passhash"})) {
$passhash = $xmlparse->{'attribute'}->{"passhash"}->{'value'};
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid characters in password hash")
if (! ($passhash =~ /^\$\d\$\w*\$[\w\/\.]*$/ ||
$passhash =~ /^[\w\/\.]*$/));
}
my $user = User->Lookup($login);
if (defined($user)) {
return GeniResponse->Create(GENIRESPONSE_ALREADYEXISTS, undef,
......@@ -182,6 +193,14 @@ sub AddUser($)
$user->SetStatus($User::USERSTATUS_ACTIVE);
$user->Update({"nocollabtools" => "1",
"manager_urn" => $credential->owner_urn()});
if (defined($passhash) &&
$user->SetPassword($passhash) != 0) {
GeniUtil::FlipToGeniUser();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error setting user password");
}
$output = GeniUtil::ExecQuiet("$WAP $ADDUSER $login");
if ($?) {
$user->Delete();
......@@ -314,6 +333,37 @@ sub ModifyUser($)
"Internal error modifying user");
}
unlink($filename);
#
# Look for password change. Need special treatment cause its a hash.
#
my $xmlparse = eval { XMLin($xmlgoo,
ForceArray => ["pubkeys"],
VarAttr => 'name',
ContentKey => '-content',
SuppressEmpty => undef); };
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, "$@")
if ($@);
if (exists($xmlparse->{'attribute'}->{"passhash"})) {
my $hash = $xmlparse->{'attribute'}->{"passhash"}->{'value'};
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid characters in password hash")
if (! ($hash =~ /^\$\d\$\w*\$[\w\/\.]*$/ ||
$hash =~ /^[\w\/\.]*$/));
my $uid = $user->uid();
my $safe_encoding = User::escapeshellarg($hash);
$output = GeniUtil::ExecQuiet("$WAP $CHPASS $uid $safe_encoding");
if ($?) {
GeniUtil::FlipToGeniUser();
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error modifying user password");
}
}
GeniUtil::FlipToGeniUser();
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
......
#!/usr/bin/perl -w
#
# Copyright (c) 2009-2011 University of Utah and the Flux Group.
# Copyright (c) 2009-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -49,7 +49,7 @@ 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 $MANAGEREMOTE = "$TB/sbin/manageremote -p";
my $PORTAL_ENABLE = @PORTAL_ENABLE@;
my $PORTAL_PRIMARY= @PORTAL_ISPRIMARY@;
......@@ -377,9 +377,17 @@ while (1)
next;
}
logit("Running");
#
# Lock, to avoid race with command line tool.
#
if (TBScriptLock("portal_op", 0, 30) != TBSCRIPTLOCK_OKAY()) {
logit("Could not get the lock after a long time. Trying again ...\n");
next;
}
ExportUsers();
ExportGroups();
UpdateUsers();
TBScriptUnlock();
last
if ($oneshot);
......
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