Commit d0cfcfc2 authored by Leigh B Stoller's avatar Leigh B 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