Commit c0cea001 authored by Leigh B Stoller's avatar Leigh B Stoller

Add silent (-s) and uid override (-u) options. The -u option is to

override the uid in the XML file (for portal mode).

Add support for multiple ssh keys.

Add xml tags to match the output of dumpuser.
parent 57d451ed
#!/usr/bin/perl -wT #!/usr/bin/perl -wT
# #
# EMULAB-COPYRIGHT # EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group. # Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved. # All rights reserved.
# #
use English; use English;
...@@ -15,12 +15,15 @@ use Data::Dumper; ...@@ -15,12 +15,15 @@ use Data::Dumper;
# #
sub usage() sub usage()
{ {
print("Usage: moduserinfo [-d] [-v] <xmlfile>\n"); print("Usage: moduserinfo [-d] [-v] [-u <uid>] <xmlfile>\n");
exit(-1); exit(-1);
} }
my $optlist = "dv"; my $optlist = "dvu:s";
my $debug = 0; my $debug = 0;
my $verify = 0; # Check data and return status only. my $verify = 0; # Check data and return status only.
my $silent = 0; # No email.
my $uidopt; # Use -u to override uid in the xml.
my @keyfiles = ();
# #
# Configure variables # Configure variables
...@@ -29,6 +32,7 @@ my $TB = "@prefix@"; ...@@ -29,6 +32,7 @@ my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@"; my $TBOPS = "@TBOPSEMAIL@";
my $TBAUDIT = "@TBAUDITEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@";
my $checkpass = "$TB/libexec/checkpass"; my $checkpass = "$TB/libexec/checkpass";
my $addpubkey = "$TB/sbin/addpubkey";
# #
# Untaint the path # Untaint the path
...@@ -69,6 +73,12 @@ if (defined($options{"d"})) { ...@@ -69,6 +73,12 @@ if (defined($options{"d"})) {
if (defined($options{"v"})) { if (defined($options{"v"})) {
$verify = 1; $verify = 1;
} }
if (defined($options{"s"})) {
$silent = 1;
}
if (defined($options{"u"})) {
$uidopt = $options{"u"};
}
if (@ARGV != 1) { if (@ARGV != 1) {
usage(); usage();
} }
...@@ -124,6 +134,8 @@ else { ...@@ -124,6 +134,8 @@ else {
my $SLOT_OPTIONAL = 0x1; # The field is not required. my $SLOT_OPTIONAL = 0x1; # The field is not required.
my $SLOT_REQUIRED = 0x2; # The field is required and must be non-null. my $SLOT_REQUIRED = 0x2; # The field is required and must be non-null.
my $SLOT_ADMINONLY = 0x4; # Only admins can set this field. my $SLOT_ADMINONLY = 0x4; # Only admins can set this field.
my $SLOT_SKIP = 0x8; # Handled specially so skip
# #
# XXX We should encode all of this in the DB so that we can generate the # XXX We should encode all of this in the DB so that we can generate the
# forms on the fly, as well as this checking code. # forms on the fly, as well as this checking code.
...@@ -152,12 +164,30 @@ my %xmlfields = ...@@ -152,12 +164,30 @@ my %xmlfields =
"w_password1" => ["w_password1", $SLOT_OPTIONAL], "w_password1" => ["w_password1", $SLOT_OPTIONAL],
"w_password2" => ["w_password2", $SLOT_OPTIONAL], "w_password2" => ["w_password2", $SLOT_OPTIONAL],
"user_interface" => ["user_interface", $SLOT_OPTIONAL], "user_interface" => ["user_interface", $SLOT_OPTIONAL],
"notes" => ["notes", $SLOT_OPTIONAL]); "pubkeys" => ["pubkeys", $SLOT_SKIP],
"wikiname" => ["pubkeys", $SLOT_SKIP],
# These are alternates.
"name" => ["usr_name", $SLOT_OPTIONAL],
"title" => ["usr_title", $SLOT_OPTIONAL],
"affiliation" => ["usr_affil", $SLOT_OPTIONAL],
"affiliation_abbreviation" => ["usr_affil_abbrev", $SLOT_OPTIONAL],
"shell" => ["usr_shell", $SLOT_OPTIONAL],
"URL" => ["usr_URL", $SLOT_OPTIONAL],
"email" => ["usr_email", $SLOT_OPTIONAL],
"address" => ["usr_addr", $SLOT_OPTIONAL],
"address2" => ["usr_addr2", $SLOT_OPTIONAL],
"city" => ["usr_city", $SLOT_OPTIONAL],
"state" => ["usr_state", $SLOT_OPTIONAL],
"zip" => ["usr_zip", $SLOT_OPTIONAL],
"country" => ["usr_country", $SLOT_OPTIONAL],
"phone" => ["usr_phone", $SLOT_OPTIONAL],
);
# #
# Must wrap the parser in eval since it exits on error. # Must wrap the parser in eval since it exits on error.
# #
my $xmlparse = eval { XMLin($xmlfile, my $xmlparse = eval { XMLin($xmlfile,
ForceArray => ["pubkeys"],
VarAttr => 'name', VarAttr => 'name',
ContentKey => '-content', ContentKey => '-content',
SuppressEmpty => undef); }; SuppressEmpty => undef); };
...@@ -171,6 +201,12 @@ fatal($@) ...@@ -171,6 +201,12 @@ fatal($@)
# #
my %errors = (); my %errors = ();
# Insert the user override.
if (defined($uidopt)) {
$xmlparse->{'attribute'}->{"uid"} = {};
$xmlparse->{'attribute'}->{"uid"}->{"value"} = $uidopt;
}
# #
# Make sure all the required arguments were provided. # Make sure all the required arguments were provided.
# #
...@@ -267,6 +303,8 @@ foreach $key (keys(%{ $xmlparse->{'attribute'} })) { ...@@ -267,6 +303,8 @@ foreach $key (keys(%{ $xmlparse->{'attribute'} })) {
$errors{$key} = "Administrators only" $errors{$key} = "Administrators only"
if (! $this_user->IsAdmin()); if (! $this_user->IsAdmin());
} }
next
if ($required & $SLOT_SKIP);
# Now check that the value is legal. # Now check that the value is legal.
if (! TBcheck_dbslot($value, "users", if (! TBcheck_dbslot($value, "users",
...@@ -291,8 +329,10 @@ if (!defined($target_user)) { ...@@ -291,8 +329,10 @@ if (!defined($target_user)) {
if (!$target_user->AccessCheck($this_user, TB_USERINFO_MODIFYINFO())) { if (!$target_user->AccessCheck($this_user, TB_USERINFO_MODIFYINFO())) {
UserError("UserInfo: Not enough permission"); UserError("UserInfo: Not enough permission");
} }
my $target_name = $target_user->name(); my $target_name = $target_user->name();
my $target_email = $target_user->email(); my $target_email = $target_user->email();
my $target_idx = $target_user->uid_idx();
$target_uid = $target_user->uid();
# Make sure the user name has at least two tokens! # Make sure the user name has at least two tokens!
if (exists($moduserinfo_args{"usr_name"}) && if (exists($moduserinfo_args{"usr_name"}) &&
...@@ -361,6 +401,34 @@ if (exists($moduserinfo_args{"user_interface"})) { ...@@ -361,6 +401,34 @@ if (exists($moduserinfo_args{"user_interface"})) {
} }
} }
#
# Do a check on the pubkeys if supplied. The safest thing to do is generate
# a temporary file and pass that to addpubkey to check.
#
if (exists($xmlparse->{'pubkeys'})) {
my @keys = @{ $xmlparse->{'pubkeys'} };
foreach my $key (@keys) {
my $keyfile = TBMakeTempFile("addpubkey");
fatal("Could not create tempfile")
if ($?);
open(KEY, ">> $keyfile") or
fatal("Could not open $keyfile");
print KEY $key;
close($keyfile);
if ($debug) {
print STDERR "Checking key in $keyfile ...\n";
}
my $result = `$addpubkey -n -f $keyfile`;
chomp($result);
UserError("Could not parse public key")
if ($?);
push(@keyfiles, $keyfile);
}
}
exit(0) exit(0)
if ($verify); if ($verify);
...@@ -375,6 +443,28 @@ UserError($usrerr) ...@@ -375,6 +443,28 @@ UserError($usrerr)
fatal("Could not modify user profile!") fatal("Could not modify user profile!")
if (!defined($mod_val)); if (!defined($mod_val));
#
# Do we have a keyfile? If so, rerun addpubkey for real now that the
# user is created and email is sent.
#
if (@keyfiles) {
$target_user->DeleteSSHKeys();
my $opt = ($silent ? "-s" : "");
# Set the implied user for addpubkey.
$ENV{'HTTP_INVOKING_USER'} = $target_idx;
foreach my $keyfile (@keyfiles) {
my $result = `$addpubkey $opt -u $target_uid -f $keyfile`;
chomp($result);
fatal("Could not parse public key: $result")
if ($?);
unlink($keyfile)
if (! $debug);
}
}
exit(0); exit(0);
sub fatal($) sub fatal($)
......
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